// -------- addsocket ----------------------------- // After opening a socket, call addsocket to increase maxsocket, // care for recsocket, and add socket to sock_fds. P addsocket(P fd, const struct SocketType* type, const union SocketInfo* info) { P retc = OK; struct socketstore* next; for (next = socketstore_head; next; next = next->next) if (next->fd == fd) { if (type->listener || next->type.listener) return SOCK_STATE; return OK; } if (! (next = (struct socketstore*) malloc(sizeof(struct socketstore)))) dm_error(errno, "Malloc failure creating socketstore"); next->fd = fd; next->type = *type; if (info) next->info = *info; next->pid = getpid(); next->redirector = -1; next->next = NULL; next->last = socketstore_tail; if (socketstore_tail) socketstore_tail->next = next; else socketstore_head = next; socketstore_tail = next; if (! type->fork) { if ((retc = nocloseonexec(fd))) goto ret; } else if ((retc = closeonexec(fd))) goto ret; if (type->listener) { DEBUG("add: %li", fd); FD_SET(fd, &sock_fds); if (fd >= maxsocket) maxsocket = fd+1; if (recsocket < 0) recsocket = fd; if (info->listener.recsigfd != -1 || info->listener.trecsigfd != -1) { if ((retc = forksighandler(info->listener.recsigfd, info->listener.trecsigfd, info->listener.unixport, &next->redirector))) goto ret; next->info.listener.recsigfd = -1; next->info.listener.trecsigfd = -1; } } sockprintdebug("open", next); ret: if (retc) delsocket_force(fd); return retc; }
struct dc_sink *dc_link_add_remote_sink( struct dc_link *link, const uint8_t *edid, int len, struct dc_sink_init_data *init_data) { struct dc_sink *dc_sink; enum dc_edid_status edid_status; if (len > MAX_EDID_BUFFER_SIZE) { dm_error("Max EDID buffer size breached!\n"); return NULL; } if (!init_data) { BREAK_TO_DEBUGGER(); return NULL; } if (!init_data->link) { BREAK_TO_DEBUGGER(); return NULL; } dc_sink = dc_sink_create(init_data); if (!dc_sink) return NULL; memmove(dc_sink->dc_edid.raw_edid, edid, len); dc_sink->dc_edid.length = len; if (!link_add_remote_sink_helper( link, dc_sink)) goto fail_add_sink; edid_status = dm_helpers_parse_edid_caps( link->ctx, &dc_sink->dc_edid, &dc_sink->edid_caps); if (edid_status != EDID_OK) goto fail; return dc_sink; fail: dc_link_remove_remote_sink(link, dc_sink); fail_add_sink: dc_sink_release(dc_sink); return NULL; }
P op_Xconnect(void) { #if X_DISPLAY_MISSING return NO_XWINDOWS; #else P retc; if (o_1 < FLOORopds) return OPDS_UNF; if (TAG(o_1) != (ARRAY | BYTETYPE)) return OPD_ERR; if (ARRAY_SIZE(o_1) > (P) sizeof(displayname)-1) return RNG_CHK; DEBUG("open display%s", ""); if (ARRAY_SIZE(o_1) > 0) { moveB((B *)VALUE_BASE(o_1), displayname, ARRAY_SIZE(o_1)); displayname[ARRAY_SIZE(o_1)] = '\000'; dvtdisplay = XOpenDisplay((char*)displayname); } else if ((dvtdisplay = XOpenDisplay(NULL))) { strncpy((char*)displayname, DisplayString(dvtdisplay), sizeof(displayname)-1); displayname[sizeof(displayname)-1] = '\000'; }; if (! dvtdisplay) { *displayname = '\0'; return X_BADHOST; }; setenv("DISPLAY", (char*)displayname, 1); dvtscreen = HXDefaultScreenOfDisplay(dvtdisplay); dvtrootwindow = HXDefaultRootWindow(dvtdisplay); if (HXGetWindowAttributes(dvtdisplay,dvtrootwindow,&rootwindowattr) == 0) dm_error(0, "Xwindows: no root window attributes"); ndvtwindows = 0; ncachedfonts = 0; dvtgc = HXCreateGC(dvtdisplay,dvtrootwindow,0,NULL); xsocket = ConnectionNumber(dvtdisplay); if ((retc = addsocket(xsocket, &sockettype, &defaultsocketinfo))) { if (retc == SOCK_STATE) { if (close(xsocket)) return -errno; xsocket = -1; } int_Xdisconnect(TRUE); return retc; } FREEopds = o_1; XSetErrorHandler(xerrorhandler); XSetIOErrorHandler(xioerrorhandler); return OK; #endif }
static void log_to_debug_console(struct log_entry *entry) { struct dal_logger *logger = entry->logger; if (logger->flags.bits.ENABLE_CONSOLE == 0) return; if (entry->buf_offset) { switch (entry->major) { case LOG_MAJOR_ERROR: dm_error("%s", entry->buf); break; default: dm_output_to_console("%s", entry->buf); break; } } }
int main(int argc, char *argv[]) { char* endptr; sysop = _sysop; syserrm = _syserrm; syserrc = _syserrc; check_plugin = _check_plugin; #if ENABLE_SEM do_inter_lock_init = _do_inter_lock_init; do_inter_lock_reset = _do_inter_lock_reset; do_inter_lock = _do_inter_lock; do_inter_unlock = _do_inter_unlock; #endif /*------------------------ get host name */ if (gethostname((char*)hostname,255) == -1) dm_error(errno, "gethostname"); /*------------------------ parse arguments */ if (argc != 2) usage_error(0); switch (serverport = strtol(argv[1], &endptr, 0)) { case LONG_MAX: case LONG_MIN: if (errno) usage_error(errno); } if (! *(argv[1]) || *endptr) usage_error(errno); serverport += getportoffset(); initfds(); /*------------- make server socket and listen on it ----------------- Note: all communication errors that can only be due to faulty code (rather than an external condition) are reported through 'error' and thus lead to termination of this process. */ run_dnode_mill(); }
bool hwss_wait_for_blank_complete( struct timing_generator *tg) { int counter; /* Not applicable if the pipe is not primary, save 300ms of boot time */ if (!tg->funcs->is_blanked) return true; for (counter = 0; counter < 100; counter++) { if (tg->funcs->is_blanked(tg)) break; msleep(1); } if (counter == 100) { dm_error("DC: failed to blank crtc!\n"); return false; } return true; }
static void reset_lb_on_vblank(struct dc_context *ctx) { uint32_t value, frame_count; uint32_t retry = 0; uint32_t status_pos = dm_read_reg(ctx, mmCRTC_STATUS_POSITION); /* Only if CRTC is enabled and counter is moving we wait for one frame. */ if (status_pos != dm_read_reg(ctx, mmCRTC_STATUS_POSITION)) { /* Resetting LB on VBlank */ value = dm_read_reg(ctx, mmLB_SYNC_RESET_SEL); set_reg_field_value(value, 3, LB_SYNC_RESET_SEL, LB_SYNC_RESET_SEL); set_reg_field_value(value, 1, LB_SYNC_RESET_SEL, LB_SYNC_RESET_SEL2); dm_write_reg(ctx, mmLB_SYNC_RESET_SEL, value); frame_count = dm_read_reg(ctx, mmCRTC_STATUS_FRAME_COUNT); for (retry = 100; retry > 0; retry--) { if (frame_count != dm_read_reg(ctx, mmCRTC_STATUS_FRAME_COUNT)) break; msleep(1); } if (!retry) dm_error("Frame count did not increase for 100ms.\n"); /* Resetting LB on VBlank */ value = dm_read_reg(ctx, mmLB_SYNC_RESET_SEL); set_reg_field_value(value, 2, LB_SYNC_RESET_SEL, LB_SYNC_RESET_SEL); set_reg_field_value(value, 0, LB_SYNC_RESET_SEL, LB_SYNC_RESET_SEL2); dm_write_reg(ctx, mmLB_SYNC_RESET_SEL, value); } }
void set_closesockets_atexit(void) { if (atexit(_closesockets_cleanup)) dm_error(-errno, "Setting atexit closesockets"); if (atexit(closedisplay)) dm_error(-errno, "Setting atexit closedisplay"); }
static bool construct( uint8_t num_virtual_links, struct dc *dc, struct dce110_resource_pool *pool) { unsigned int i; struct dc_context *ctx = dc->ctx; struct dc_firmware_info info; struct dc_bios *bp; struct dm_pp_static_clock_info static_clk_info = {0}; ctx->dc_bios->regs = &bios_regs; pool->base.res_cap = &res_cap; pool->base.funcs = &dce100_res_pool_funcs; pool->base.underlay_pipe_index = NO_UNDERLAY_PIPE; bp = ctx->dc_bios; if ((bp->funcs->get_firmware_info(bp, &info) == BP_RESULT_OK) && info.external_clock_source_frequency_for_dp != 0) { pool->base.dp_clock_source = dce100_clock_source_create(ctx, bp, CLOCK_SOURCE_ID_EXTERNAL, NULL, true); pool->base.clock_sources[0] = dce100_clock_source_create(ctx, bp, CLOCK_SOURCE_ID_PLL0, &clk_src_regs[0], false); pool->base.clock_sources[1] = dce100_clock_source_create(ctx, bp, CLOCK_SOURCE_ID_PLL1, &clk_src_regs[1], false); pool->base.clock_sources[2] = dce100_clock_source_create(ctx, bp, CLOCK_SOURCE_ID_PLL2, &clk_src_regs[2], false); pool->base.clk_src_count = 3; } else { pool->base.dp_clock_source = dce100_clock_source_create(ctx, bp, CLOCK_SOURCE_ID_PLL0, &clk_src_regs[0], true); pool->base.clock_sources[0] = dce100_clock_source_create(ctx, bp, CLOCK_SOURCE_ID_PLL1, &clk_src_regs[1], false); pool->base.clock_sources[1] = dce100_clock_source_create(ctx, bp, CLOCK_SOURCE_ID_PLL2, &clk_src_regs[2], false); pool->base.clk_src_count = 2; } if (pool->base.dp_clock_source == NULL) { dm_error("DC: failed to create dp clock source!\n"); BREAK_TO_DEBUGGER(); goto res_create_fail; } for (i = 0; i < pool->base.clk_src_count; i++) { if (pool->base.clock_sources[i] == NULL) { dm_error("DC: failed to create clock sources!\n"); BREAK_TO_DEBUGGER(); goto res_create_fail; } } pool->base.display_clock = dce_disp_clk_create(ctx, &disp_clk_regs, &disp_clk_shift, &disp_clk_mask); if (pool->base.display_clock == NULL) { dm_error("DC: failed to create display clock!\n"); BREAK_TO_DEBUGGER(); goto res_create_fail; } pool->base.dmcu = dce_dmcu_create(ctx, &dmcu_regs, &dmcu_shift, &dmcu_mask); if (pool->base.dmcu == NULL) { dm_error("DC: failed to create dmcu!\n"); BREAK_TO_DEBUGGER(); goto res_create_fail; } pool->base.abm = dce_abm_create(ctx, &abm_regs, &abm_shift, &abm_mask); if (pool->base.abm == NULL) { dm_error("DC: failed to create abm!\n"); BREAK_TO_DEBUGGER(); goto res_create_fail; } /* get static clock information for PPLIB or firmware, save * max_clock_state */ if (dm_pp_get_static_clocks(ctx, &static_clk_info)) pool->base.display_clock->max_clks_state = static_clk_info.max_clocks_state; { struct irq_service_init_data init_data; init_data.ctx = dc->ctx; pool->base.irqs = dal_irq_service_dce110_create(&init_data); if (!pool->base.irqs) goto res_create_fail; } /************************************************* * Resource + asic cap harcoding * *************************************************/ pool->base.underlay_pipe_index = NO_UNDERLAY_PIPE; pool->base.pipe_count = res_cap.num_timing_generator; pool->base.timing_generator_count = pool->base.res_cap->num_timing_generator; dc->caps.max_downscale_ratio = 200; dc->caps.i2c_speed_in_khz = 40; dc->caps.max_cursor_size = 128; dc->caps.dual_link_dvi = true; for (i = 0; i < pool->base.pipe_count; i++) { pool->base.timing_generators[i] = dce100_timing_generator_create( ctx, i, &dce100_tg_offsets[i]); if (pool->base.timing_generators[i] == NULL) { BREAK_TO_DEBUGGER(); dm_error("DC: failed to create tg!\n"); goto res_create_fail; } pool->base.mis[i] = dce100_mem_input_create(ctx, i); if (pool->base.mis[i] == NULL) { BREAK_TO_DEBUGGER(); dm_error( "DC: failed to create memory input!\n"); goto res_create_fail; } pool->base.ipps[i] = dce100_ipp_create(ctx, i); if (pool->base.ipps[i] == NULL) { BREAK_TO_DEBUGGER(); dm_error( "DC: failed to create input pixel processor!\n"); goto res_create_fail; } pool->base.transforms[i] = dce100_transform_create(ctx, i); if (pool->base.transforms[i] == NULL) { BREAK_TO_DEBUGGER(); dm_error( "DC: failed to create transform!\n"); goto res_create_fail; } pool->base.opps[i] = dce100_opp_create(ctx, i); if (pool->base.opps[i] == NULL) { BREAK_TO_DEBUGGER(); dm_error( "DC: failed to create output pixel processor!\n"); goto res_create_fail; } } dc->caps.max_planes = pool->base.pipe_count; if (!resource_construct(num_virtual_links, dc, &pool->base, &res_create_funcs)) goto res_create_fail; /* Create hardware sequencer */ dce100_hw_sequencer_construct(dc); return true; res_create_fail: destruct(pool); return false; }
static bool construct( uint8_t num_virtual_links, struct dc *dc, struct dce110_resource_pool *pool) { unsigned int i; struct dc_context *ctx = dc->ctx; struct irq_service_init_data irq_init_data; ctx->dc_bios->regs = &bios_regs; pool->base.res_cap = &res_cap; pool->base.funcs = &dce120_res_pool_funcs; /* TODO: Fill more data from GreenlandAsicCapability.cpp */ pool->base.pipe_count = res_cap.num_timing_generator; pool->base.underlay_pipe_index = NO_UNDERLAY_PIPE; dc->caps.max_downscale_ratio = 200; dc->caps.i2c_speed_in_khz = 100; dc->caps.max_cursor_size = 128; dc->caps.dual_link_dvi = true; dc->debug = debug_defaults; /************************************************* * Create resources * *************************************************/ pool->base.clock_sources[DCE120_CLK_SRC_PLL0] = dce120_clock_source_create(ctx, ctx->dc_bios, CLOCK_SOURCE_COMBO_PHY_PLL0, &clk_src_regs[0], false); pool->base.clock_sources[DCE120_CLK_SRC_PLL1] = dce120_clock_source_create(ctx, ctx->dc_bios, CLOCK_SOURCE_COMBO_PHY_PLL1, &clk_src_regs[1], false); pool->base.clock_sources[DCE120_CLK_SRC_PLL2] = dce120_clock_source_create(ctx, ctx->dc_bios, CLOCK_SOURCE_COMBO_PHY_PLL2, &clk_src_regs[2], false); pool->base.clock_sources[DCE120_CLK_SRC_PLL3] = dce120_clock_source_create(ctx, ctx->dc_bios, CLOCK_SOURCE_COMBO_PHY_PLL3, &clk_src_regs[3], false); pool->base.clock_sources[DCE120_CLK_SRC_PLL4] = dce120_clock_source_create(ctx, ctx->dc_bios, CLOCK_SOURCE_COMBO_PHY_PLL4, &clk_src_regs[4], false); pool->base.clock_sources[DCE120_CLK_SRC_PLL5] = dce120_clock_source_create(ctx, ctx->dc_bios, CLOCK_SOURCE_COMBO_PHY_PLL5, &clk_src_regs[5], false); pool->base.clk_src_count = DCE120_CLK_SRC_TOTAL; pool->base.dp_clock_source = dce120_clock_source_create(ctx, ctx->dc_bios, CLOCK_SOURCE_ID_DP_DTO, &clk_src_regs[0], true); for (i = 0; i < pool->base.clk_src_count; i++) { if (pool->base.clock_sources[i] == NULL) { dm_error("DC: failed to create clock sources!\n"); BREAK_TO_DEBUGGER(); goto clk_src_create_fail; } } pool->base.display_clock = dce120_disp_clk_create(ctx); if (pool->base.display_clock == NULL) { dm_error("DC: failed to create display clock!\n"); BREAK_TO_DEBUGGER(); goto disp_clk_create_fail; } pool->base.dmcu = dce_dmcu_create(ctx, &dmcu_regs, &dmcu_shift, &dmcu_mask); if (pool->base.dmcu == NULL) { dm_error("DC: failed to create dmcu!\n"); BREAK_TO_DEBUGGER(); goto res_create_fail; } pool->base.abm = dce_abm_create(ctx, &abm_regs, &abm_shift, &abm_mask); if (pool->base.abm == NULL) { dm_error("DC: failed to create abm!\n"); BREAK_TO_DEBUGGER(); goto res_create_fail; } irq_init_data.ctx = dc->ctx; pool->base.irqs = dal_irq_service_dce120_create(&irq_init_data); if (!pool->base.irqs) goto irqs_create_fail; for (i = 0; i < pool->base.pipe_count; i++) { pool->base.timing_generators[i] = dce120_timing_generator_create( ctx, i, &dce120_tg_offsets[i]); if (pool->base.timing_generators[i] == NULL) { BREAK_TO_DEBUGGER(); dm_error("DC: failed to create tg!\n"); goto controller_create_fail; } pool->base.mis[i] = dce120_mem_input_create(ctx, i); if (pool->base.mis[i] == NULL) { BREAK_TO_DEBUGGER(); dm_error( "DC: failed to create memory input!\n"); goto controller_create_fail; } pool->base.ipps[i] = dce120_ipp_create(ctx, i); if (pool->base.ipps[i] == NULL) { BREAK_TO_DEBUGGER(); dm_error( "DC: failed to create input pixel processor!\n"); goto controller_create_fail; } pool->base.transforms[i] = dce120_transform_create(ctx, i); if (pool->base.transforms[i] == NULL) { BREAK_TO_DEBUGGER(); dm_error( "DC: failed to create transform!\n"); goto res_create_fail; } pool->base.opps[i] = dce120_opp_create( ctx, i); if (pool->base.opps[i] == NULL) { BREAK_TO_DEBUGGER(); dm_error( "DC: failed to create output pixel processor!\n"); } } if (!resource_construct(num_virtual_links, dc, &pool->base, &res_create_funcs)) goto res_create_fail; /* Create hardware sequencer */ if (!dce120_hw_sequencer_create(dc)) goto controller_create_fail; dc->caps.max_planes = pool->base.pipe_count; bw_calcs_init(dc->bw_dceip, dc->bw_vbios, dc->ctx->asic_id); bw_calcs_data_update_from_pplib(dc); return true; irqs_create_fail: controller_create_fail: disp_clk_create_fail: clk_src_create_fail: res_create_fail: destruct(pool); return false; }
int main(void) { LBIG memsetup[5] = { 1000, 100, 20, 10, 200 }; B* startup_dvt; B fromconsoleframe[FRAMEBYTES], *sf; P nb, retc,tnb; B *sysdict, *userdict, *p; int sufd; sysop = _sysop; syserrc = _syserrc; syserrm = _syserrm; createfds(); serialized = TRUE; // no serialize operator /*----------------- SIGNALS that we wish to handle -------------------*/ /* FPU indigestion is recorded in the numovf flag; we do not wish to be killed by it */ numovf = FALSE; signal(SIGFPE, SIGFPEhandler); /* The broken pipe signal is ignored, so it cannot kill us; it will pop up in attempts to send on a broken connection */ signal(SIGPIPE, SIG_IGN); /* We use alarms to time-limit read/write operations on sockets */ timeout = FALSE; signal(SIGALRM, SIGALRMhandler); /* The interrupt signal is produced by the control-c key of the console keyboard, it triggers the execution of 'abort' */ abortflag = FALSE; signal(SIGINT, SIGINThandler); /*--------------------- set up the tiny D machine ------------------- Not so tiny for the dvt, this should be good for most work */ if (makeDmemory(memsetup)) dm_error(0, "D memory"); /*----------------- construct frames for use in execution of D code */ makename((B*) "error", errorframe); ATTR(errorframe) = ACTIVE; makename((B*) "fromconsole", fromconsoleframe); ATTR(fromconsoleframe) = ACTIVE; TAG(FREEvm) = STRING; ARRAY_SIZE(FREEvm) = 1024; VALUE_PTR(FREEvm) = FREEvm + FRAMEBYTES; ATTR(FREEvm) = ACTIVE; moveframe(FREEvm, inputframe); FREEvm += FRAMEBYTES + 1024; /* The system dictionary is created in the workspace of the tiny D machine. If the operator 'makeVM' is used to create a large D machine, this larger machine inherits the system dictionary of the tiny machine. We memorize the pointers of the tiny D memory so we can revert to the tiny setup. */ if ((sysdict = makeopdict((B *)sysop, syserrc, syserrm)) == (B *)(-1L)) dm_error(0,"Cannot make system dictionary"); if ((userdict = makedict(memsetup[4])) == (B *)(-1L)) dm_error(0,"Cannot make user dictionary"); /* The first two dictionaries on the dicts are systemdict and userdict; they are not removable */ moveframe (sysdict-FRAMEBYTES,FREEdicts); FREEdicts += FRAMEBYTES; moveframe (userdict-FRAMEBYTES,FREEdicts); FREEdicts += FRAMEBYTES; setupdirs(); fprintf(stderr, "Startup dir: %s\n", startup_dir); /*----------- read startup_dvt.d and push on execs ----------*/ startup_dvt = (B*)strcat(strcpy(malloc(strlen((char*)startup_dir) + strlen("/startup_dgen.d") + 1), startup_dir), "/startup_dgen.d"); if ((sufd = open((char*)startup_dvt, O_RDONLY)) == -1) dm_error(errno,"Opening %s", startup_dvt); tnb = 0; sf = FREEvm; p = sf + FRAMEBYTES; TAG(sf) = ARRAY | BYTETYPE; ATTR(sf) = READONLY | ACTIVE | PARENT; VALUE_BASE(sf) = (P)p; while (((nb = read(sufd,p,CEILvm-p)) > 0) && (p <= CEILvm)) { tnb += nb; p += nb; } if (nb == -1) dm_error(errno,"Reading %s", startup_dvt); if (p == CEILvm) dm_error(ENOMEM,"%s > VM", startup_dvt); ARRAY_SIZE(sf) = tnb; FREEvm += DALIGN(FRAMEBYTES + tnb); moveframe(sf,x1); FREEexecs = x2; /*-------------------------- run the D mill --------------------- */ while (1) { switch(retc = exec(1000)) { case MORE: continue; case DONE: moveframe(fromconsoleframe, x1); FREEexecs=x2; continue; case ABORT: printf("Failure...\n"); exitval = ((UL32) EXIT_FAILURE) & 0xFF; die(); case QUIT: case TERM: printf("Success..\n"); die(); default: break; } /*----------------------- error handler ---------------------------*/ makeerror(retc, errsource); }; } /* of main */
static bool create_links( struct dc *dc, uint32_t num_virtual_links) { int i; int connectors_num; struct dc_bios *bios = dc->ctx->dc_bios; dc->link_count = 0; connectors_num = bios->funcs->get_connectors_number(bios); if (connectors_num > ENUM_ID_COUNT) { dm_error( "DC: Number of connectors %d exceeds maximum of %d!\n", connectors_num, ENUM_ID_COUNT); return false; } if (connectors_num == 0 && num_virtual_links == 0) { dm_error("DC: Number of connectors is zero!\n"); } dm_output_to_console( "DC: %s: connectors_num: physical:%d, virtual:%d\n", __func__, connectors_num, num_virtual_links); for (i = 0; i < connectors_num; i++) { struct link_init_data link_init_params = {0}; struct dc_link *link; link_init_params.ctx = dc->ctx; /* next BIOS object table connector */ link_init_params.connector_index = i; link_init_params.link_index = dc->link_count; link_init_params.dc = dc; link = link_create(&link_init_params); if (link) { dc->links[dc->link_count] = link; link->dc = dc; ++dc->link_count; } } for (i = 0; i < num_virtual_links; i++) { struct dc_link *link = kzalloc(sizeof(*link), GFP_KERNEL); struct encoder_init_data enc_init = {0}; if (link == NULL) { BREAK_TO_DEBUGGER(); goto failed_alloc; } link->link_index = dc->link_count; dc->links[dc->link_count] = link; dc->link_count++; link->ctx = dc->ctx; link->dc = dc; link->connector_signal = SIGNAL_TYPE_VIRTUAL; link->link_id.type = OBJECT_TYPE_CONNECTOR; link->link_id.id = CONNECTOR_ID_VIRTUAL; link->link_id.enum_id = ENUM_ID_1; link->link_enc = kzalloc(sizeof(*link->link_enc), GFP_KERNEL); if (!link->link_enc) { BREAK_TO_DEBUGGER(); goto failed_alloc; } link->link_status.dpcd_caps = &link->dpcd_caps; enc_init.ctx = dc->ctx; enc_init.channel = CHANNEL_ID_UNKNOWN; enc_init.hpd_source = HPD_SOURCEID_UNKNOWN; enc_init.transmitter = TRANSMITTER_UNKNOWN; enc_init.connector = link->link_id; enc_init.encoder.type = OBJECT_TYPE_ENCODER; enc_init.encoder.id = ENCODER_ID_INTERNAL_VIRTUAL; enc_init.encoder.enum_id = ENUM_ID_1; virtual_link_encoder_construct(link->link_enc, &enc_init); } return true; failed_alloc: return false; }
static bool construct(struct dc *dc, const struct dc_init_data *init_params) { struct dal_logger *logger; struct dc_context *dc_ctx = kzalloc(sizeof(*dc_ctx), GFP_KERNEL); struct bw_calcs_dceip *dc_dceip = kzalloc(sizeof(*dc_dceip), GFP_KERNEL); struct bw_calcs_vbios *dc_vbios = kzalloc(sizeof(*dc_vbios), GFP_KERNEL); #ifdef CONFIG_DRM_AMD_DC_DCN1_0 struct dcn_soc_bounding_box *dcn_soc = kzalloc(sizeof(*dcn_soc), GFP_KERNEL); struct dcn_ip_params *dcn_ip = kzalloc(sizeof(*dcn_ip), GFP_KERNEL); #endif enum dce_version dc_version = DCE_VERSION_UNKNOWN; if (!dc_dceip) { dm_error("%s: failed to create dceip\n", __func__); goto fail; } dc->bw_dceip = dc_dceip; if (!dc_vbios) { dm_error("%s: failed to create vbios\n", __func__); goto fail; } dc->bw_vbios = dc_vbios; #ifdef CONFIG_DRM_AMD_DC_DCN1_0 if (!dcn_soc) { dm_error("%s: failed to create dcn_soc\n", __func__); goto fail; } dc->dcn_soc = dcn_soc; if (!dcn_ip) { dm_error("%s: failed to create dcn_ip\n", __func__); goto fail; } dc->dcn_ip = dcn_ip; #endif if (!dc_ctx) { dm_error("%s: failed to create ctx\n", __func__); goto fail; } dc->current_state = dc_create_state(); if (!dc->current_state) { dm_error("%s: failed to create validate ctx\n", __func__); goto fail; } dc_ctx->cgs_device = init_params->cgs_device; dc_ctx->driver_context = init_params->driver; dc_ctx->dc = dc; dc_ctx->asic_id = init_params->asic_id; /* Create logger */ logger = dal_logger_create(dc_ctx, init_params->log_mask); if (!logger) { /* can *not* call logger. call base driver 'print error' */ dm_error("%s: failed to create Logger!\n", __func__); goto fail; } dc_ctx->logger = logger; dc->ctx = dc_ctx; dc->ctx->dce_environment = init_params->dce_environment; dc_version = resource_parse_asic_id(init_params->asic_id); dc->ctx->dce_version = dc_version; #if defined(CONFIG_DRM_AMD_DC_FBC) dc->ctx->fbc_gpu_addr = init_params->fbc_gpu_addr; #endif /* Resource should construct all asic specific resources. * This should be the only place where we need to parse the asic id */ if (init_params->vbios_override) dc_ctx->dc_bios = init_params->vbios_override; else { /* Create BIOS parser */ struct bp_init_data bp_init_data; bp_init_data.ctx = dc_ctx; bp_init_data.bios = init_params->asic_id.atombios_base_address; dc_ctx->dc_bios = dal_bios_parser_create( &bp_init_data, dc_version); if (!dc_ctx->dc_bios) { ASSERT_CRITICAL(false); goto fail; } dc_ctx->created_bios = true; } /* Create I2C AUX */ dc_ctx->i2caux = dal_i2caux_create(dc_ctx); if (!dc_ctx->i2caux) { ASSERT_CRITICAL(false); goto fail; } /* Create GPIO service */ dc_ctx->gpio_service = dal_gpio_service_create( dc_version, dc_ctx->dce_environment, dc_ctx); if (!dc_ctx->gpio_service) { ASSERT_CRITICAL(false); goto fail; } dc->res_pool = dc_create_resource_pool( dc, init_params->num_virtual_links, dc_version, init_params->asic_id); if (!dc->res_pool) goto fail; dc_resource_state_construct(dc, dc->current_state); if (!create_links(dc, init_params->num_virtual_links)) goto fail; allocate_dc_stream_funcs(dc); return true; fail: destruct(dc); return false; }
DM_INLINE_STATIC void usage_error(int errno_) { dm_error(errno_, "usage is: dnode portnumber [setsid=0/1]"); }
static bool construct( uint8_t num_virtual_links, struct dc *dc, struct dce110_resource_pool *pool) { unsigned int i; int j; struct dc_context *ctx = dc->ctx; struct irq_service_init_data irq_init_data; bool harvest_enabled = ASICREV_IS_VEGA20_P(ctx->asic_id.hw_internal_rev); uint32_t pipe_fuses; ctx->dc_bios->regs = &bios_regs; pool->base.res_cap = &res_cap; pool->base.funcs = &dce120_res_pool_funcs; /* TODO: Fill more data from GreenlandAsicCapability.cpp */ pool->base.pipe_count = res_cap.num_timing_generator; pool->base.timing_generator_count = pool->base.res_cap->num_timing_generator; pool->base.underlay_pipe_index = NO_UNDERLAY_PIPE; dc->caps.max_downscale_ratio = 200; dc->caps.i2c_speed_in_khz = 100; dc->caps.max_cursor_size = 128; dc->caps.dual_link_dvi = true; dc->caps.psp_setup_panel_mode = true; dc->debug = debug_defaults; /************************************************* * Create resources * *************************************************/ pool->base.clock_sources[DCE120_CLK_SRC_PLL0] = dce120_clock_source_create(ctx, ctx->dc_bios, CLOCK_SOURCE_COMBO_PHY_PLL0, &clk_src_regs[0], false); pool->base.clock_sources[DCE120_CLK_SRC_PLL1] = dce120_clock_source_create(ctx, ctx->dc_bios, CLOCK_SOURCE_COMBO_PHY_PLL1, &clk_src_regs[1], false); pool->base.clock_sources[DCE120_CLK_SRC_PLL2] = dce120_clock_source_create(ctx, ctx->dc_bios, CLOCK_SOURCE_COMBO_PHY_PLL2, &clk_src_regs[2], false); pool->base.clock_sources[DCE120_CLK_SRC_PLL3] = dce120_clock_source_create(ctx, ctx->dc_bios, CLOCK_SOURCE_COMBO_PHY_PLL3, &clk_src_regs[3], false); pool->base.clock_sources[DCE120_CLK_SRC_PLL4] = dce120_clock_source_create(ctx, ctx->dc_bios, CLOCK_SOURCE_COMBO_PHY_PLL4, &clk_src_regs[4], false); pool->base.clock_sources[DCE120_CLK_SRC_PLL5] = dce120_clock_source_create(ctx, ctx->dc_bios, CLOCK_SOURCE_COMBO_PHY_PLL5, &clk_src_regs[5], false); pool->base.clk_src_count = DCE120_CLK_SRC_TOTAL; pool->base.dp_clock_source = dce120_clock_source_create(ctx, ctx->dc_bios, CLOCK_SOURCE_ID_DP_DTO, &clk_src_regs[0], true); for (i = 0; i < pool->base.clk_src_count; i++) { if (pool->base.clock_sources[i] == NULL) { dm_error("DC: failed to create clock sources!\n"); BREAK_TO_DEBUGGER(); goto clk_src_create_fail; } } pool->base.dccg = dce120_dccg_create(ctx); if (pool->base.dccg == NULL) { dm_error("DC: failed to create display clock!\n"); BREAK_TO_DEBUGGER(); goto dccg_create_fail; } pool->base.dmcu = dce_dmcu_create(ctx, &dmcu_regs, &dmcu_shift, &dmcu_mask); if (pool->base.dmcu == NULL) { dm_error("DC: failed to create dmcu!\n"); BREAK_TO_DEBUGGER(); goto res_create_fail; } pool->base.abm = dce_abm_create(ctx, &abm_regs, &abm_shift, &abm_mask); if (pool->base.abm == NULL) { dm_error("DC: failed to create abm!\n"); BREAK_TO_DEBUGGER(); goto res_create_fail; } irq_init_data.ctx = dc->ctx; pool->base.irqs = dal_irq_service_dce120_create(&irq_init_data); if (!pool->base.irqs) goto irqs_create_fail; /* retrieve valid pipe fuses */ if (harvest_enabled) pipe_fuses = read_pipe_fuses(ctx); /* index to valid pipe resource */ j = 0; for (i = 0; i < pool->base.pipe_count; i++) { if (harvest_enabled) { if ((pipe_fuses & (1 << i)) != 0) { dm_error("DC: skip invalid pipe %d!\n", i); continue; } } pool->base.timing_generators[j] = dce120_timing_generator_create( ctx, i, &dce120_tg_offsets[i]); if (pool->base.timing_generators[j] == NULL) { BREAK_TO_DEBUGGER(); dm_error("DC: failed to create tg!\n"); goto controller_create_fail; } pool->base.mis[j] = dce120_mem_input_create(ctx, i); if (pool->base.mis[j] == NULL) { BREAK_TO_DEBUGGER(); dm_error( "DC: failed to create memory input!\n"); goto controller_create_fail; } pool->base.ipps[j] = dce120_ipp_create(ctx, i); if (pool->base.ipps[i] == NULL) { BREAK_TO_DEBUGGER(); dm_error( "DC: failed to create input pixel processor!\n"); goto controller_create_fail; } pool->base.transforms[j] = dce120_transform_create(ctx, i); if (pool->base.transforms[i] == NULL) { BREAK_TO_DEBUGGER(); dm_error( "DC: failed to create transform!\n"); goto res_create_fail; } pool->base.opps[j] = dce120_opp_create( ctx, i); if (pool->base.opps[j] == NULL) { BREAK_TO_DEBUGGER(); dm_error( "DC: failed to create output pixel processor!\n"); } /* check next valid pipe */ j++; } for (i = 0; i < pool->base.res_cap->num_ddc; i++) { pool->base.engines[i] = dce120_aux_engine_create(ctx, i); if (pool->base.engines[i] == NULL) { BREAK_TO_DEBUGGER(); dm_error( "DC:failed to create aux engine!!\n"); goto res_create_fail; } pool->base.hw_i2cs[i] = dce120_i2c_hw_create(ctx, i); if (pool->base.hw_i2cs[i] == NULL) { BREAK_TO_DEBUGGER(); dm_error( "DC:failed to create i2c engine!!\n"); goto res_create_fail; } pool->base.sw_i2cs[i] = NULL; } /* valid pipe num */ pool->base.pipe_count = j; pool->base.timing_generator_count = j; if (!resource_construct(num_virtual_links, dc, &pool->base, &res_create_funcs)) goto res_create_fail; /* Create hardware sequencer */ if (!dce120_hw_sequencer_create(dc)) goto controller_create_fail; dc->caps.max_planes = pool->base.pipe_count; bw_calcs_init(dc->bw_dceip, dc->bw_vbios, dc->ctx->asic_id); bw_calcs_data_update_from_pplib(dc); return true; irqs_create_fail: controller_create_fail: dccg_create_fail: clk_src_create_fail: res_create_fail: destruct(pool); return false; }