/** * \brief Application entry point for smc_lcd example. * * \return Unused (ANSI-C compatibility). */ int main(void) { sysclk_init(); board_init(); /** Initialize debug console */ configure_console(); /* Disable the watchdog */ WDT->WDT_MR = WDT_MR_WDDIS; /** Configura o timer */ configure_tc(); /* Configura os botões */ configure_buttons(); configure_display(); init_tela(); /** Draw text, image and basic shapes on the LCD */ //ili93xx_set_foreground_color(COLOR_BLACK); //ili93xx_draw_string(10, 20, (uint8_t *)"ili93xx_lcd example"); while (1) { } }
static int vd_control(vout_display_t *vd, int query, va_list args) { vout_display_sys_t *sys = vd->sys; vout_display_cfg_t cfg; const vout_display_cfg_t *tmp_cfg; const video_format_t *tmp_fmt; int ret = VLC_EGENERIC; switch (query) { case VOUT_DISPLAY_HIDE_MOUSE: case VOUT_DISPLAY_CHANGE_WINDOW_STATE: ret = VLC_SUCCESS; break; case VOUT_DISPLAY_CHANGE_DISPLAY_SIZE: tmp_cfg = va_arg(args, const vout_display_cfg_t *); if (tmp_cfg->display.width == sys->display_width && tmp_cfg->display.height == sys->display_height) { cfg = *vd->cfg; cfg.display.width = sys->display_width; cfg.display.height = sys->display_height; if (configure_display(vd, &cfg, NULL) >= 0) ret = VLC_SUCCESS; } break; case VOUT_DISPLAY_CHANGE_SOURCE_ASPECT: case VOUT_DISPLAY_CHANGE_SOURCE_CROP: tmp_fmt = va_arg(args, const video_format_t *); if (configure_display(vd, NULL, tmp_fmt) >= 0) ret = VLC_SUCCESS; break; case VOUT_DISPLAY_CHANGE_FULLSCREEN: case VOUT_DISPLAY_CHANGE_ZOOM: case VOUT_DISPLAY_RESET_PICTURES: msg_Warn(vd, "Unsupported control query %d", query); break; default: msg_Warn(vd, "Unknown control query %d", query); break; } return ret; }
static void vd_display(vout_display_t *vd, picture_t *picture, subpicture_t *subpicture) { vout_display_sys_t *sys = vd->sys; picture_sys_t *pic_sys = picture->p_sys; MMAL_BUFFER_HEADER_T *buffer = pic_sys->buffer; MMAL_STATUS_T status; if (picture->format.i_frame_rate != sys->i_frame_rate || picture->format.i_frame_rate_base != sys->i_frame_rate_base || picture->b_progressive != sys->b_progressive || picture->b_top_field_first != sys->b_top_field_first) { sys->b_top_field_first = picture->b_top_field_first; sys->b_progressive = picture->b_progressive; sys->i_frame_rate = picture->format.i_frame_rate; sys->i_frame_rate_base = picture->format.i_frame_rate_base; configure_display(vd, NULL, &picture->format); } if (!pic_sys->displayed || !sys->opaque) { buffer->cmd = 0; buffer->length = sys->input->buffer_size; vlc_mutex_lock(&sys->buffer_mutex); while (sys->buffers_in_transit >= MAX_BUFFERS_IN_TRANSIT) vlc_cond_wait(&sys->buffer_cond, &sys->buffer_mutex); status = mmal_port_send_buffer(sys->input, buffer); if (status == MMAL_SUCCESS) ++sys->buffers_in_transit; vlc_mutex_unlock(&sys->buffer_mutex); if (status != MMAL_SUCCESS) { msg_Err(vd, "Failed to send buffer to input port. Frame dropped"); picture_Release(picture); } pic_sys->displayed = true; } else { picture_Release(picture); } display_subpicture(vd, subpicture); if (subpicture) subpicture_Delete(subpicture); if (sys->next_phase_check == 0 && sys->adjust_refresh_rate) maintain_phase_sync(vd); sys->next_phase_check = (sys->next_phase_check + 1) % PHASE_CHECK_INTERVAL; }
/*! * This function sets up planes, pipes, and ports * with the configuration passed in and returnes either one * or two display handle lists. * * @param driver_handle from igd_init_driver(). * @param primary on return, this points to a list of displays. * @param primary_ptinfo incoming timing info for the primary. * @param primary_fbinfo incoming framebuffer info. * @param secondary on return, this points to a list of displays. * @param secondary_fbinfo incoming framebuffer info. * @param dc display configuration * @param flags modify function behavior * * @return 0 on success * @return -IGD_INVAL on failure */ int igd_alter_displays( igd_driver_h driver_handle, igd_display_h *_primary, igd_display_info_t *primary_pt_info, igd_framebuffer_info_t *primary_fb_info, igd_display_h *_secondary, igd_display_info_t *secondary_pt_info, igd_framebuffer_info_t *secondary_fb_info, unsigned long dc, unsigned long flags) { igd_context_t *context = (igd_context_t *)driver_handle; igd_display_context_t **primary = (igd_display_context_t **)_primary; igd_display_context_t **secondary = (igd_display_context_t **)_secondary; igd_framebuffer_info_t *fb_info = NULL; igd_display_context_t *display = NULL,*tv_display=NULL; int p; int ret; unsigned short tv_port_num=0; int p_chng = 1, s_chng = 1; unsigned char disable_plane_pipe = 0; unsigned long current_dc; #if 0 /* Ian Elliott is taking this out ... see comment below */ #ifndef CONFIG_MICRO igd_framebuffer_info_t *plane_fb_info = NULL; #endif #endif /* 0 -- Ian is taking this out */ EMGD_TRACE_ENTER; /* * Make sure the DC is valid * * vBIOS won't be able to do this every time, for now only have * the drivers's do the check. */ #ifndef CONFIG_MICRO if (dc && !dsp_valid_dc(dc, 0)) { EMGD_ERROR_EXIT("Invalid display configuration: 0x%08lx", dc); return -IGD_ERROR_INVAL; } #endif /* * Can all display_info's and fb_info's be NULL? I.E. make this * function do an alloc of display handles only? If so, then * check for that condition and return without error. Otherwise * return an error. */ if (dc && (!primary_pt_info && !primary_fb_info) && (!secondary_pt_info && !secondary_fb_info)) { EMGD_ERROR_EXIT("Invalid timing and framebuffer info"); return -IGD_ERROR_INVAL; } #ifndef CONFIG_MICRO /* FIXME: GDK Change this to dispatch->idle() */ if (dsp_wait_rb(mode_context->context) != 0) { return -IGD_ERROR_INVAL; } #endif /* If seamless request is NOT set , then do reset_plane_pipe_ports * else delay it until we cannot support it. * If seamless is requested by the user and we CAN support it * then we need to make sure reset_plane_pipe_ports is NOT * called. That's the whole point anyway. Not to reset anything * during seamless transition */ if(mode_context->seamless != TRUE) { /* Reset planes/pipes/ports before doing first alter display */ if (mode_context->first_alter) { mode_context->dispatch->reset_plane_pipe_ports( mode_context->context); mode_context->first_alter = FALSE; } } current_dc = *(context->mod_dispatch.dsp_current_dc); #ifndef CONFIG_MICRO /* Check if platform needs force alter * to make sure we run tuning code. This * is for TNC-B0 workaround.*/ if (mode_context->dispatch->dsp_is_force_alter_required){ if (mode_context->dispatch-> dsp_is_force_alter_required(context-> mod_dispatch.dsp_display_list[IGD_DC_PRIMARY(current_dc)], current_dc, dc)){ flags |= IGD_FORCE_ALTER; } } #endif /* * Turn off the planes, pipes, and ports associated with the current * DC. However, limit the change to the primary if the secondary * display handle is NULL or limit the change to the secondary if the * the pimary display handle is NULL. */ for (p = 7; p > 0; p--) { if (p > 4) { display = NULL; if (DC_PORT_NUMBER(current_dc, p)) { display = context->mod_dispatch. dsp_display_list[IGD_DC_SECONDARY(current_dc)]; s_chng = TIMING_CHANGED(display, dc, current_dc, secondary_pt_info, secondary_fb_info, (unsigned long)0xfff00000, flags); } if (s_chng && display && secondary) { /* if the port is TV, then don't set the power to S3 as this causes * blank screen and system hang on LVDS on FSDOS, probably because the * external clock needs to be on till the pipes and * DPLLs are off */ if(PORT(display,DC_PORT_NUMBER(current_dc, p))->pd_type == PD_DISPLAY_TVOUT) { tv_display = display; tv_port_num = DC_PORT_NUMBER(current_dc, p); } else { ret = mode_context->dispatch->program_port(display, DC_PORT_NUMBER(current_dc, p), FALSE); } /* The secondary pipe master */ if (p == 5) { disable_plane_pipe = 1; } } } else { display = NULL; if (DC_PORT_NUMBER(current_dc, p)) { display = context->mod_dispatch. dsp_display_list[IGD_DC_PRIMARY(current_dc)]; p_chng = TIMING_CHANGED(display, dc, current_dc, primary_pt_info, primary_fb_info, (unsigned long)0x000ffff0, flags); } if (p_chng && display && primary) { /* if the port is TV, then don't set the power to S3 as this causes * blank screen and system hang on LVDS on FSDOS, probably because the * external clock needs to be on till the pipes and * DPLLs are off */ if(PORT(display,DC_PORT_NUMBER(current_dc, p))->pd_type == PD_DISPLAY_TVOUT) { tv_display = display; tv_port_num = DC_PORT_NUMBER(current_dc, p); } else { ret = mode_context->dispatch->program_port(display, DC_PORT_NUMBER(current_dc, p), FALSE); } /* The primary pipe master */ if (p == 1) { disable_plane_pipe = 1; } } } /* Disable plane and pipe after disabling the ports */ if (disable_plane_pipe) { if(mode_context->dispatch->full) { mode_context->dispatch->full->program_cursor(display, FALSE); } mode_context->dispatch->program_plane(display, FALSE); mode_context->dispatch->program_pipe(display, FALSE); /*pipes and dplls are off, now turn off tv port */ if(tv_display) { ret = mode_context->dispatch->program_port(tv_display, tv_port_num, FALSE); tv_display = NULL; } disable_plane_pipe = 0; } } #ifndef CONFIG_MICRO /* If DC is zero, then return here. A zero dc turns everything off */ /* This never happens for VBIOS since it only always calls * * alter_displays at the same point with the same valid DC */ if (!dc) { int i; mode_context->dispatch->reset_plane_pipe_ports(mode_context->context); /* Should de-allocate everything here */ dsp_alloc(driver_handle, dc, flags); /* * FIXME: This should be done inside dsp alloc, mode module does * not own this information. * When dc = 0, set all displays allocated to 0. */ for (i=0; i<IGD_MAX_PORTS+1; i++) { if (context->mod_dispatch.dsp_display_list[i]) { context->mod_dispatch.dsp_display_list[i]->allocated = 0; } context->mod_dispatch.dsp_display_list[i] = NULL; } return 0; } #endif /* * Check the DC (display configuration). If it is the same as the * current configuration, then don't change any allocations, only * modify the framebuffers and timings. */ if (dc != current_dc) { EMGD_DEBUG("Allocate display handles based on DC"); #ifndef CONFIG_MICRO if (swap_required(current_dc, dc, primary)) { swap_fb_cursor(); } #endif /* * This function should never be called after VBIOS initialization * * The dsp_alloc is discarded after VBIOS init and is over- * * written by font tables. Thus in VBIOS IAL, alter_displays * * is never get called with a different DC from the 1st time * */ dsp_alloc(driver_handle, dc, flags); } /* Attach the displays to the caller's pointers */ if (primary) { *primary = context->mod_dispatch.dsp_display_list[IGD_DC_PRIMARY(dc)]; #ifndef CONFIG_MICRO if (*primary && context->mod_dispatch.alloc_queues) { ret = context->mod_dispatch.alloc_queues(driver_handle, (*primary)->pipe, flags); if (ret) { EMGD_ERROR("unable to allocate command queues"); } } #endif } if (secondary) { EMGD_DEBUG("Attaching display 1 to secondary pointer"); *secondary = context->mod_dispatch. dsp_display_list[IGD_DC_SECONDARY(dc)]; #ifndef CONFIG_MICRO if (*secondary && context->mod_dispatch.alloc_queues) { ret = context->mod_dispatch.alloc_queues(driver_handle, (*secondary)->pipe, flags); if (ret) { EMGD_ERROR("unable to allocate command queues"); } } #endif } /* * Configure the primary display. This configures the timings and the * framebuffer. Once configured, it turns everythying on. */ if(primary && *primary && (primary_pt_info || primary_fb_info) && p_chng) { EMGD_DEBUG("Configure primary timings"); /* make framebuffer changes */ if (primary_fb_info) { /* set up new frame buffer info */ fb_info = primary_fb_info; } else { fb_info = PLANE(*primary)->fb_info; } ret = configure_display(driver_handle, (igd_display_context_t *)(*primary), primary_pt_info, fb_info, dc, 0, 4, flags); if (ret) { EMGD_DEBUG("Primary display disabled."); } } /* * Configure the secondary display. This configures the timings and the * framebuffer. Once configured, it turns everythying on. * * How close is this code to the code for the primary? Could this * be moved to a separate function? */ if (secondary != NULL) { #ifndef CONFIG_MICRO /* * In the case where we are in extended or clone and our pipe is not * turned on, we need to turn the pipes on. * We can run into this situation on pre-Cantiga Gen platforms on Linux * where LVDS was the primary display and was assigned PIPE B. Then we * are switching from LVDS to another display and that other display * wants to take PIPE A. In this case PIPE B will be turned on, the * display's new port will take PIPE A and turn on PIPE A. The second * display thinks it is still PIPE A and nothing has changed for it. * In this case where our pipe is not turned on, we need to let the * system know that something has changed. */ if ((IGD_DC_CLONE(dc) || IGD_DC_EXTENDED(dc)) && !(EMGD_READ32(MMIO(*secondary) + PIPE(*secondary)->pipe_reg) & 0x80000000)) { s_chng = 1; } #endif EMGD_DEBUG("Starting secondary pipe programming"); if ((*secondary != NULL) && (secondary_pt_info || secondary_fb_info) && s_chng){ /* * Configure the framebuffer. For clone, it is the same * as the primary. For DIH, it is a unique fb. */ EMGD_DEBUG("configure secondary framebuffer"); if (dc & IGD_DISPLAY_CONFIG_CLONE) { fb_info = PLANE(*primary)->fb_info; } else { if (secondary_fb_info) { fb_info = secondary_fb_info; } else { fb_info = PLANE(*secondary)->fb_info; } } ret = configure_display(driver_handle, (igd_display_context_t *)(*secondary), secondary_pt_info, fb_info, dc, 4, 7, flags); if (ret) { EMGD_DEBUG("Secondary display disabled."); EMGD_ERROR("Secondary display disabled."); } } } else { EMGD_DEBUG("Skipped secondary programming, NULL handle"); } /* * Workaround: wait for Vblank to avoid people accessing display * plane registers before the register is updated properly. */ if (primary && *primary) { EMGD_DEBUG("Wait for vblank on primary display (%p)", primary); EMGD_DEBUG("Wait for vblank on primary display (%p)", *primary); mode_context->dispatch->wait_vblank(*primary); } else if (secondary && *secondary) { EMGD_DEBUG("Wait for vblank on secondary display"); mode_context->dispatch->wait_vblank(*secondary); } EMGD_TRACE_EXIT; return 0; }