void OMAPLFBDisplayInit(void) { struct omap_overlay* overlayptr = 0; unsigned int i = 0; unsigned int numoverlays = 0; // there is tv and lcd managers... we only care about lcd at this time. lcd_mgr = omap_dss_get_overlay_manager(OMAP_DSS_OVL_MGR_LCD); #ifdef CONFIG_TVOUT_SHOLEST tv_mgr = omap_dss_get_overlay_manager(OMAP_DSS_OVL_MGR_TV); #endif if(!lcd_mgr) { DEBUG_PRINTK((KERN_INFO DRIVER_PREFIX ": OMAPLFBSetDisplayInfo couldn't find lcd overlay manager\n")); return; } numoverlays = omap_dss_get_num_overlays(); if( numoverlays == 0) { DEBUG_PRINTK((KERN_INFO DRIVER_PREFIX ": OMAPLFBSetDisplayInfo couldn't find any overlays\n")); return; } for( i = 0; i < numoverlays; i++ ) { overlayptr = omap_dss_get_overlay(i); if( strncmp( overlayptr->name, "gfx", 3 ) == 0) { DEBUG_PRINTK((KERN_INFO DRIVER_PREFIX ": OMAPLFBSetDisplayInfo found GFX overlay\n")); omap_gfxoverlay = overlayptr; break; } } #ifdef CONFIG_TVOUT_SHOLEST for( i = 0; i < numoverlays; i++ ) { overlayptr = omap_dss_get_overlay(i); if( strncmp( overlayptr->name, "vid2", 4 ) == 0) { DEBUG_PRINTK((KERN_INFO DRIVER_PREFIX ": OMAPLFBSetDisplayInfo found GFX overlay\n")); omap_vid2overlay = overlayptr; break; } } #endif if( omap_gfxoverlay == 0 ) { DEBUG_PRINTK((KERN_INFO DRIVER_PREFIX ": OMAPLFBSetDisplayInfo GFX overlay no found\n")); return; } omap_gfxoverlay->get_overlay_info( omap_gfxoverlay, &gfxoverlayinfo ); #ifdef CONFIG_TVOUT_SHOLEST omap_vid2overlay->get_overlay_info(omap_vid2overlay, &vid2overlayinfo); #endif fb_info = registered_fb[0]; }
static int omapvout_dss_get_overlays(struct omap_overlay **gfx, struct omap_overlay **vid1, struct omap_overlay **vid2) { struct omap_overlay *t; int num_ovlys; int i; *gfx = NULL; *vid1 = NULL; *vid2 = NULL; num_ovlys = omap_dss_get_num_overlays(); for (i = 0; i < num_ovlys; i++) { t = omap_dss_get_overlay(i); switch (t->id) { case OMAP_DSS_GFX: *gfx = t; break; case OMAP_DSS_VIDEO1: *vid1 = t; break; case OMAP_DSS_VIDEO2: *vid2 = t; break; } } if (*gfx && *vid1 && *vid2) return 0; return -EINVAL; }
/* connect overlays to the new device, if not already connected. if force * selected, connect always. */ void dss_recheck_connections(struct omap_dss_device *dssdev, bool force) { int i; struct omap_overlay_manager *lcd_mgr; struct omap_overlay_manager *tv_mgr; struct omap_overlay_manager *lcd2_mgr = NULL; struct omap_overlay_manager *mgr = NULL; lcd_mgr = omap_dss_get_overlay_manager(OMAP_DSS_OVL_MGR_LCD); tv_mgr = omap_dss_get_overlay_manager(OMAP_DSS_OVL_MGR_TV); if (cpu_is_omap44xx()) lcd2_mgr = omap_dss_get_overlay_manager(OMAP_DSS_OVL_MGR_LCD2); if (dssdev->channel == OMAP_DSS_CHANNEL_LCD2) { if(lcd2_mgr == NULL) return; //LGE_CHANGE [[email protected]] 2011-03-02, P920 : For WBT if (!lcd2_mgr->device || force) { if (lcd2_mgr->device) lcd2_mgr->unset_device(lcd2_mgr); lcd2_mgr->set_device(lcd2_mgr, dssdev); mgr = lcd2_mgr; } } else if (dssdev->type != OMAP_DISPLAY_TYPE_VENC && dssdev->type != OMAP_DISPLAY_TYPE_HDMI) { if (!lcd_mgr->device || force) { if (lcd_mgr->device) lcd_mgr->unset_device(lcd_mgr); lcd_mgr->set_device(lcd_mgr, dssdev); mgr = lcd_mgr; } } if (dssdev->type == OMAP_DISPLAY_TYPE_VENC || dssdev->type == OMAP_DISPLAY_TYPE_HDMI) { if (!tv_mgr->device || force) { if (tv_mgr->device) tv_mgr->unset_device(tv_mgr); tv_mgr->set_device(tv_mgr, dssdev); mgr = tv_mgr; } } //LGE_CHANGE_S [[email protected]] 2010-1-03, P920 : prevent to blink . if(dssdev->type != OMAP_DISPLAY_TYPE_HDMI) { //LGE_CHANGE_E [[email protected]] 2011-01-03 if (mgr) { for (i = 0; i < MAX_DSS_OVERLAYS; i++) { struct omap_overlay *ovl; ovl = omap_dss_get_overlay(i); if (!ovl->manager || force) { if (ovl->manager) omap_dss_unset_manager(ovl); omap_dss_set_manager(ovl, mgr); } } } //LGE_CHANGE_S [[email protected]] 2010-1-03, P920 : prevent to blink . } //LGE_CHANGE_E [[email protected]] 2011-01-03 }
/* connect overlays to the new device, if not already connected. if force * selected, connect always. */ void dss_recheck_connections(struct omap_dss_device *dssdev, bool force) { int i; struct omap_overlay_manager *lcd_mgr; struct omap_overlay_manager *tv_mgr; struct omap_overlay_manager *lcd2_mgr = NULL; struct omap_overlay_manager *mgr = NULL; lcd_mgr = omap_dss_get_overlay_manager(OMAP_DSS_OVL_MGR_LCD); tv_mgr = omap_dss_get_overlay_manager(OMAP_DSS_OVL_MGR_TV); if (dss_has_feature(FEAT_MGR_LCD2)) lcd2_mgr = omap_dss_get_overlay_manager(OMAP_DSS_OVL_MGR_LCD2); if (dssdev->channel == OMAP_DSS_CHANNEL_LCD2) { if (!lcd2_mgr->device || force) { if (lcd2_mgr->device) lcd2_mgr->unset_device(lcd2_mgr); lcd2_mgr->set_device(lcd2_mgr, dssdev); mgr = lcd2_mgr; } } else if (dssdev->type != OMAP_DISPLAY_TYPE_VENC && dssdev->type != OMAP_DISPLAY_TYPE_HDMI) { if (!lcd_mgr->device || force) { if (lcd_mgr->device) lcd_mgr->unset_device(lcd_mgr); lcd_mgr->set_device(lcd_mgr, dssdev); mgr = lcd_mgr; } } if (dssdev->type == OMAP_DISPLAY_TYPE_VENC || dssdev->type == OMAP_DISPLAY_TYPE_HDMI) { if (!tv_mgr->device || force) { if (tv_mgr->device) tv_mgr->unset_device(tv_mgr); tv_mgr->set_device(tv_mgr, dssdev); mgr = tv_mgr; } } if (mgr) { dispc_runtime_get(); for (i = 0; i < dss_feat_get_num_ovls(); i++) { struct omap_overlay *ovl; ovl = omap_dss_get_overlay(i); if (!ovl->manager || force) { if (ovl->manager) ovl->unset_manager(ovl); ovl->set_manager(ovl, mgr); } } dispc_runtime_put(); } }
static void GetLcdManager(void){ struct omap_overlay *ovl; ovl = omap_dss_get_overlay(0); lcd_mgr = omap_dss_get_overlay_manager(ovl->manager->id); if(!lcd_mgr) { DEBUG_PRINTK((KERN_INFO DRIVER_PREFIX ": GetLcdManager couldn't find lcd overlay manager\n")); } }
/* connect overlays to the new device, if not already connected. if force * selected, connect always. */ void dss_recheck_connections(struct omap_dss_device *dssdev, bool force) { int i; struct omap_overlay_manager *lcd_mgr; struct omap_overlay_manager *tv_mgr; struct omap_overlay_manager *lcd2_mgr = NULL; struct omap_overlay_manager *mgr = NULL; lcd_mgr = omap_dss_get_overlay_manager(OMAP_DSS_OVL_MGR_LCD); tv_mgr = omap_dss_get_overlay_manager(OMAP_DSS_OVL_MGR_TV); if (cpu_is_omap44xx()) lcd2_mgr = omap_dss_get_overlay_manager(OMAP_DSS_OVL_MGR_LCD2); if (dssdev->channel == OMAP_DSS_CHANNEL_LCD2) { if (!lcd2_mgr->device || force) { if (lcd2_mgr->device) lcd2_mgr->unset_device(lcd2_mgr); lcd2_mgr->set_device(lcd2_mgr, dssdev); mgr = lcd2_mgr; } } else if (dssdev->type != OMAP_DISPLAY_TYPE_VENC && dssdev->type != OMAP_DISPLAY_TYPE_HDMI) { if (!lcd_mgr->device || force) { if (lcd_mgr->device) lcd_mgr->unset_device(lcd_mgr); lcd_mgr->set_device(lcd_mgr, dssdev); mgr = lcd_mgr; } } if (dssdev->type == OMAP_DISPLAY_TYPE_VENC || dssdev->type == OMAP_DISPLAY_TYPE_HDMI) { if (!tv_mgr->device || force) { if (tv_mgr->device) tv_mgr->unset_device(tv_mgr); tv_mgr->set_device(tv_mgr, dssdev); mgr = tv_mgr; } } if (mgr) { for (i = 0; i < MAX_DSS_OVERLAYS; i++) { struct omap_overlay *ovl; ovl = omap_dss_get_overlay(i); if (!ovl->manager || force) { if (ovl->manager) omap_dss_unset_manager(ovl); omap_dss_set_manager(ovl, mgr); } } } }
/* * Connect dssdev to a manager if the manager is free or if force is specified. * Connect all overlays to that manager if they are free or if force is * specified. */ static int dss_init_connections(struct omap_dss_device *dssdev, bool force) { struct omap_dss_output *out; struct omap_overlay_manager *mgr; int i, r; out = omapdss_get_output_from_dssdev(dssdev); WARN_ON(dssdev->output); WARN_ON(out->device); r = omapdss_output_set_device(out, dssdev); if (r) { DSSERR("failed to connect output to new device\n"); return r; } mgr = omap_dss_get_overlay_manager(dssdev->channel); if (mgr->output && !force) return 0; if (mgr->output) mgr->unset_output(mgr); r = mgr->set_output(mgr, out); if (r) { DSSERR("failed to connect manager to output of new device\n"); /* remove the output-device connection we just made */ omapdss_output_unset_device(out); return r; } for (i = 0; i < omap_dss_get_num_overlays(); ++i) { struct omap_overlay *ovl = omap_dss_get_overlay(i); if (!ovl->manager || force) { if (ovl->manager) ovl->unset_manager(ovl); r = ovl->set_manager(ovl, mgr); if (r) { DSSERR("failed to set initial overlay\n"); return r; } } } return 0; }
/*This one needs to be to set the ovl info to dirty*/ static void dpi_start_auto_update(struct omap_dss_device *dssdev) { int i; for (i = 0; i < omap_dss_get_num_overlays(); ++i) { struct omap_overlay *ovl; ovl = omap_dss_get_overlay(i); if (ovl->manager == dssdev->manager) ovl->info_dirty = true; } dssdev->manager->apply(dssdev->manager); }
int omapvout_dss_init(struct omapvout_device *vout, enum omap_plane plane) { struct omap_overlay *ovly; int rc = 0; int i; int cnt; if (vout->dss) { rc = -EINVAL; goto failed; } vout->dss = kzalloc(sizeof(struct omapvout_dss), GFP_KERNEL); if (vout->dss == NULL) { rc = -ENOMEM; goto failed; } /* Retrieve the desired DSS overlay object */ vout->dss->overlay = NULL; cnt = omap_dss_get_num_overlays(); for (i = 0; i < cnt; i++) { ovly = omap_dss_get_overlay(i); if (ovly->id == plane) { vout->dss->overlay = ovly; break; } } if (vout->dss->overlay == NULL) { DBG("No overlay %d found\n", plane); rc = -ENODEV; goto failed_mem; } rc = omapvout_dss_acquire_vrfb(vout); if (rc != 0) { DBG("VRFB allocation failed\n"); goto failed_mem; } vout->dss->vout = vout; return rc; failed_mem: kfree(vout->dss); failed: return rc; }
static void dump_video_chains(void) { int i; DBG("dumping video chains: "); for (i = 0; i < omap_dss_get_num_overlays(); i++) { struct omap_overlay *ovl = omap_dss_get_overlay(i); struct omap_overlay_manager *mgr = ovl->manager; struct omap_dss_device *dssdev = mgr ? mgr->device : NULL; if (dssdev) { DBG("%d: %s -> %s -> %s", i, ovl->name, mgr->name, dssdev->name); } else if (mgr) { DBG("%d: %s -> %s", i, ovl->name, mgr->name); } else { DBG("%d: %s", i, ovl->name); } } }
/*This one needs to be to set the ovl info to dirty*/ static void dpi_start_auto_update(struct omap_dss_device *dssdev) { int i; DSSDBG("starting auto update\n"); for (i = 0; i < omap_dss_get_num_overlays(); ++i) { struct omap_overlay *ovl; ovl = omap_dss_get_overlay(i); if (!ovl){ WARN_ON(1); continue; } if (ovl->manager == dssdev->manager) ovl->info_dirty = true; printk(KERN_ERR "ovl[%d]->manager = %s", i, ovl->manager->name); } if (dssdev->manager) dssdev->manager->apply(dssdev->manager); }
void dss_read_ovl2mgr_platform_cfg(struct omap_dss_device *dssdev, struct omap_ovl2mgr_mapping *overlay_mappings, int cnt) { struct omap_overlay_manager *lcd_mgr; struct omap_overlay_manager *tv_mgr; struct omap_overlay_manager *lcd2_mgr = NULL; struct omap_overlay_manager *mgr = NULL; int i = 0; lcd_mgr = omap_dss_get_overlay_manager(OMAP_DSS_OVL_MGR_LCD); tv_mgr = omap_dss_get_overlay_manager(OMAP_DSS_OVL_MGR_TV); if (cpu_is_omap44xx()) lcd2_mgr = omap_dss_get_overlay_manager(OMAP_DSS_OVL_MGR_LCD2); for (i = 0; i < cnt; i++) { struct omap_overlay *ovl; ovl = omap_dss_get_overlay(overlay_mappings[i].overlay_idx); switch (overlay_mappings[i].overlay_mgr) { case OMAP_DSS_OVL_MGR_LCD: mgr = lcd_mgr; break; case OMAP_DSS_OVL_MGR_TV: mgr = tv_mgr; break; case OMAP_DSS_OVL_MGR_LCD2: mgr = lcd2_mgr; break; default: continue; } if (mgr) { if (ovl->manager) omap_dss_unset_manager(ovl); omap_dss_set_manager(ovl, mgr); } } }
static int omap_modeset_init(struct drm_device *dev) { const struct omap_drm_platform_data *pdata = dev->dev->platform_data; struct omap_kms_platform_data *kms_pdata = NULL; struct omap_drm_private *priv = dev->dev_private; struct omap_dss_device *dssdev = NULL; int i, j; unsigned int connected_connectors = 0; drm_mode_config_init(dev); if (pdata && pdata->kms_pdata) { kms_pdata = pdata->kms_pdata; /* if platform data is provided by the board file, use it to * control which overlays, managers, and devices we own. */ for (i = 0; i < kms_pdata->mgr_cnt; i++) { struct omap_overlay_manager *mgr = omap_dss_get_overlay_manager( kms_pdata->mgr_ids[i]); create_encoder(dev, mgr); } for (i = 0; i < kms_pdata->dev_cnt; i++) { struct omap_dss_device *dssdev = omap_dss_find_device( (void *)kms_pdata->dev_names[i], match_dev_name); if (!dssdev) { dev_warn(dev->dev, "no such dssdev: %s\n", kms_pdata->dev_names[i]); continue; } create_connector(dev, dssdev); } connected_connectors = detect_connectors(dev); j = 0; for (i = 0; i < kms_pdata->ovl_cnt; i++) { struct omap_overlay *ovl = omap_dss_get_overlay(kms_pdata->ovl_ids[i]); create_crtc(dev, ovl, &j, connected_connectors); } for (i = 0; i < kms_pdata->pln_cnt; i++) { struct omap_overlay *ovl = omap_dss_get_overlay(kms_pdata->pln_ids[i]); create_plane(dev, ovl, (1 << priv->num_crtcs) - 1); } } else { /* otherwise just grab up to CONFIG_DRM_OMAP_NUM_CRTCS and try * to make educated guesses about everything else */ int max_overlays = min(omap_dss_get_num_overlays(), num_crtc); for (i = 0; i < omap_dss_get_num_overlay_managers(); i++) { create_encoder(dev, omap_dss_get_overlay_manager(i)); } for_each_dss_dev(dssdev) { create_connector(dev, dssdev); } connected_connectors = detect_connectors(dev); j = 0; for (i = 0; i < max_overlays; i++) { create_crtc(dev, omap_dss_get_overlay(i), &j, connected_connectors); } /* use any remaining overlays as drm planes */ for (; i < omap_dss_get_num_overlays(); i++) { struct omap_overlay *ovl = omap_dss_get_overlay(i); create_plane(dev, ovl, (1 << priv->num_crtcs) - 1); } } /* for now keep the mapping of CRTCs and encoders static.. */ for (i = 0; i < priv->num_encoders; i++) { struct drm_encoder *encoder = priv->encoders[i]; struct omap_overlay_manager *mgr = omap_encoder_get_manager(encoder); encoder->possible_crtcs = (1 << priv->num_crtcs) - 1; DBG("%s: possible_crtcs=%08x", mgr->name, encoder->possible_crtcs); } dump_video_chains(); dev->mode_config.min_width = 32; dev->mode_config.min_height = 32; /* note: eventually will need some cpu_is_omapXYZ() type stuff here * to fill in these limits properly on different OMAP generations.. */ dev->mode_config.max_width = 2048; dev->mode_config.max_height = 2048; dev->mode_config.funcs = &omap_mode_config_funcs; return 0; }
static void OMAPLFBFliepNoLock_HDMI(OMAPLFB_SWAPCHAIN *psSwapChain, OMAPLFB_DEVINFO *psDevInfo, struct omapfb_info *ofbi, struct fb_info *framebuffer, unsigned long fb_offset) { struct omap_overlay *ovl_hdmi; struct omap_overlay_info info; struct omap_overlay *hdmi; struct omap_overlay_manager *manager; bool overlay_change_requested = false; enum omap_dss_overlay_s3d_type s3d_type_in_video_hdmi = omap_dss_overlay_s3d_none; ovl_hdmi = omap_dss_get_overlay(3); if(ovl_hdmi->info.enabled) s3d_type_in_video_hdmi = ovl_hdmi->info.s3d_type; hdmi = psSwapChain->stHdmiTiler.overlay; manager = hdmi->manager; hdmi->get_overlay_info(hdmi, &info); //not good... if ( omap_overlay_info_req[hdmi->id].status==2 ) { info.enabled = omap_overlay_info_req[hdmi->id].enabled; info.rotation = omap_overlay_info_req[hdmi->id].rotation; info.pos_x = omap_overlay_info_req[hdmi->id].pos_x; info.pos_y = omap_overlay_info_req[hdmi->id].pos_y; info.out_width = omap_overlay_info_req[hdmi->id].out_width; info.out_height = omap_overlay_info_req[hdmi->id].out_height; info.global_alpha = omap_overlay_info_req[hdmi->id].global_alpha; info.zorder = omap_overlay_info_req[hdmi->id].zorder; printk("GUI HDMI layer change requested. req_enabled(%d)\n", omap_overlay_info_req[hdmi->id].enabled); omap_overlay_info_req[hdmi->id].status = 0; overlay_change_requested = true; } if ( info.enabled ) { mutex_lock(&psSwapChain->stHdmiTiler.lock); if ( !psSwapChain->stHdmiTiler.alloc ) { // if ( AllocTilerForHdmi(psSwapChain, psDevInfo) ) { ERROR_PRINTK("Tiler memory for HDMI GUI cloning is not allocated\n"); mutex_unlock(&psSwapChain->stHdmiTiler.lock); return; // } } if ( psSwapChain->stHdmiTiler.alloc ) //if Tiler memory is allocated { unsigned long line_offset; unsigned long w, h; unsigned long src_stride, dst_stride; unsigned long i; unsigned char *dst, *src; unsigned long pStride; u32 j, *src_4, *dst_4, *dst1_4; int ch; src_stride = psDevInfo->sFBInfo.ulByteStride; dst_stride = psSwapChain->stHdmiTiler.vStride; line_offset = fb_offset / src_stride; h = psDevInfo->sFBInfo.ulHeight; w = psDevInfo->sFBInfo.ulWidth; pStride = psSwapChain->stHdmiTiler.pStride; //Copy dst = (unsigned char*)psSwapChain->stHdmiTiler.vAddr + (line_offset * dst_stride); src = (unsigned char*)framebuffer->screen_base + fb_offset; DEBUG_PRINTK("Copy Start h:%d, src:0x%p src_stride:%d, dst:0x%p dst_stride:%d, line offset:%d, pStride:%d\n", h, src, src_stride, dst, dst_stride, line_offset, pStride); if( psSwapChain->s3d_type==omap_dss_overlay_s3d_side_by_side && s3d_type_in_video_hdmi == omap_dss_overlay_s3d_top_bottom) { for(j=0; j<h/2; j++) { src_4 = (u32 *)(src + src_stride*j); dst_4 = (u32 *)(dst + dst_stride*2*j); dst1_4 = (u32 *)(dst + dst_stride*2*j + w*2); for(i=0;i<w/2;i++) { *dst_4++ = *src_4; *dst1_4++ = *src_4++; src_4++; } src_4 = (u32 *)(src + src_stride*j); dst_4 = (u32 *)(dst + dst_stride*(2*j+1)); dst1_4 = (u32 *)(dst + dst_stride*(2*j+1) + w*2); for(i=0;i<w/2;i++) { *dst_4++ = *src_4; *dst1_4++ = *src_4++; src_4++; } } info.s3d_type = omap_dss_overlay_s3d_top_bottom; } else { if(hdmi_dma.state == HDMI_DMA_DONE) { ch = hdmi_dma.frame_pos; hdmi->get_overlay_info(hdmi, &hdmi_dma.info[ch]); hdmi_dma.hdmi = hdmi; printk("S:%x\n", psSwapChain->stHdmiTiler.pAddr + (h * pStride * ch)); omap_set_dma_transfer_params(hdmi_dma.lch, OMAP_DMA_DATA_TYPE_S32, src_stride>>2, h, 0, 0, 0); omap_set_dma_src_params(hdmi_dma.lch, 0, OMAP_DMA_AMODE_POST_INC, framebuffer->fix.smem_start + fb_offset, 1, 1); omap_set_dma_dest_params(hdmi_dma.lch, 0, OMAP_DMA_AMODE_DOUBLE_IDX, psSwapChain->stHdmiTiler.pAddr + (h * pStride * ch), 1, pStride - src_stride + 1 ); omap_dma_set_prio_lch(hdmi_dma.lch, DMA_CH_PRIO_HIGH, DMA_CH_PRIO_HIGH); omap_set_dma_src_burst_mode(hdmi_dma.lch, OMAP_DMA_DATA_BURST_16); omap_set_dma_dest_burst_mode(hdmi_dma.lch, OMAP_DMA_DATA_BURST_16); omap_start_dma(hdmi_dma.lch); hdmi_dma.state = HDMI_DMA_TRANSFERRING; if ( omap_overlay_info_req[hdmi->id].status==2 ) { hdmi_dma.info[ch].enabled = omap_overlay_info_req[hdmi->id].enabled; hdmi_dma.info[ch].rotation = omap_overlay_info_req[hdmi->id].rotation; hdmi_dma.info[ch].pos_x = omap_overlay_info_req[hdmi->id].pos_x; hdmi_dma.info[ch].pos_y = omap_overlay_info_req[hdmi->id].pos_y; hdmi_dma.info[ch].out_width = omap_overlay_info_req[hdmi->id].out_width; hdmi_dma.info[ch].out_height = omap_overlay_info_req[hdmi->id].out_height; hdmi_dma.info[ch].global_alpha = omap_overlay_info_req[hdmi->id].global_alpha; hdmi_dma.info[ch].zorder = omap_overlay_info_req[hdmi->id].zorder; } //fill info //@todo not good find another way later hdmi_dma.info[ch].color_mode = ofbi->overlays[0]->info.color_mode; hdmi_dma.info[ch].paddr = psSwapChain->stHdmiTiler.pAddr + (h * pStride * ch); hdmi_dma.info[ch].vaddr = NULL; //no need if ( hdmi_dma.info[ch].rotation==OMAP_DSS_ROT_90 || hdmi_dma.info[ch].rotation==OMAP_DSS_ROT_270 ) { hdmi_dma.info[ch].width = h; hdmi_dma.info[ch].height = w; hdmi_dma.info[ch].screen_width = h; } else { hdmi_dma.info[ch].width =w; hdmi_dma.info[ch].height = h; hdmi_dma.info[ch].screen_width = w; } hdmi_dma.info[ch].rotation_type = OMAP_DSS_ROT_TILER; hdmi_dma.info[ch].s3d_type = psSwapChain->s3d_type; hdmi_dma.curr_frame = hdmi_dma.frame_pos; if( ++hdmi_dma.frame_pos >= HDMI_DMA_MAX ) hdmi_dma.frame_pos = 0; if( omap_overlay_info_req[hdmi->id].status == 2) { omap_overlay_info_req[hdmi->id].status = 0; } } else printk("DOLCOM : DMA busy!!!!!!!!!!!!!!!!!\n");
static void dispc_error_worker(struct work_struct *work) { int i; u32 errors; unsigned long flags; static const unsigned fifo_underflow_bits[] = { DISPC_IRQ_GFX_FIFO_UNDERFLOW, DISPC_IRQ_VID1_FIFO_UNDERFLOW, DISPC_IRQ_VID2_FIFO_UNDERFLOW, DISPC_IRQ_VID3_FIFO_UNDERFLOW, }; spin_lock_irqsave(&dispc_compat.irq_lock, flags); errors = dispc_compat.error_irqs; dispc_compat.error_irqs = 0; spin_unlock_irqrestore(&dispc_compat.irq_lock, flags); dispc_runtime_get(); for (i = 0; i < omap_dss_get_num_overlays(); ++i) { struct omap_overlay *ovl; unsigned bit; ovl = omap_dss_get_overlay(i); bit = fifo_underflow_bits[i]; if (bit & errors) { DSSERR("FIFO UNDERFLOW on %s, disabling the overlay\n", ovl->name); dispc_ovl_enable(ovl->id, false); dispc_mgr_go(ovl->manager->id); msleep(50); } } for (i = 0; i < omap_dss_get_num_overlay_managers(); ++i) { struct omap_overlay_manager *mgr; unsigned bit; mgr = omap_dss_get_overlay_manager(i); bit = dispc_mgr_get_sync_lost_irq(i); if (bit & errors) { int j; DSSERR("SYNC_LOST on channel %s, restarting the output " "with video overlays disabled\n", mgr->name); dss_mgr_disable(mgr); for (j = 0; j < omap_dss_get_num_overlays(); ++j) { struct omap_overlay *ovl; ovl = omap_dss_get_overlay(j); if (ovl->id != OMAP_DSS_GFX && ovl->manager == mgr) ovl->disable(ovl); } dss_mgr_enable(mgr); } } if (errors & DISPC_IRQ_OCP_ERR) { DSSERR("OCP_ERR\n"); for (i = 0; i < omap_dss_get_num_overlay_managers(); ++i) { struct omap_overlay_manager *mgr; mgr = omap_dss_get_overlay_manager(i); dss_mgr_disable(mgr); } } spin_lock_irqsave(&dispc_compat.irq_lock, flags); dispc_compat.irq_error_mask |= errors; _omap_dispc_set_irqs(); spin_unlock_irqrestore(&dispc_compat.irq_lock, flags); dispc_runtime_put(); }
static int omap_modeset_init(struct drm_device *dev) { const struct omap_gpu_platform_data *pdata = dev->dev->platform_data; struct omap_gpu_private *priv = dev->dev_private; struct omap_dss_device *dssdev = NULL; int i, j; unsigned int connected_connectors = 0; /* create encoders for each manager */ int create_encoder(int i) { struct omap_overlay_manager *mgr = omap_dss_get_overlay_manager(i); struct drm_encoder *encoder = omap_encoder_init(dev, mgr); if (!encoder) { dev_err(dev->dev, "could not create encoder\n"); return -ENOMEM; } priv->encoders[priv->num_encoders++] = encoder; return 0; } /* create connectors for each display device */ int create_connector(struct omap_dss_device *dssdev) { static struct notifier_block *notifier; struct drm_connector *connector; if (!dssdev->driver) { dev_warn(dev->dev, "%s has no driver.. skipping it\n", dssdev->name); return 0; } if (!(dssdev->driver->get_timings || dssdev->driver->get_edid)) { dev_warn(dev->dev, "%s driver does not support " "get_timings or get_edid.. skipping it!\n", dssdev->name); return 0; } connector = omap_connector_init(dev, get_connector_type(dssdev->type), dssdev); if (!connector) { dev_err(dev->dev, "could not create connector\n"); return -ENOMEM; } /* track what is already connected.. rather than looping thru all * connectors twice later, first for connected then for remainder * (which could be a race condition if connected status changes) */ if (omap_connector_detect (connector) == connector_status_connected) { connected_connectors |= (1 << priv->num_connectors); } priv->connectors[priv->num_connectors++] = connector; notifier = kzalloc(sizeof(struct notifier_block), GFP_KERNEL); notifier->notifier_call = omap_gpu_notifier; omap_dss_add_notify(dssdev, notifier); for (j = 0; j < priv->num_encoders; j++) { struct omap_overlay_manager *mgr = omap_encoder_get_manager(priv->encoders[j]); if (mgr->device == dssdev) { drm_mode_connector_attach_encoder(connector, priv->encoders[j]); } } return 0; } /* create up to max_overlays CRTCs mapping to overlays.. by default, * connect the overlays to different managers/encoders, giving priority * to encoders connected to connectors with a detected connection */ int create_crtc(int i) { struct omap_overlay *ovl = omap_dss_get_overlay(i); struct omap_overlay_manager *mgr = NULL; struct drm_crtc *crtc; if (ovl->manager) { DBG("disconnecting %s from %s", ovl->name, ovl->manager->name); ovl->unset_manager(ovl); } /* find next best connector... ones with detected connection first */ while (j < priv->num_connectors && !mgr) { if (connected_connectors & (1 << j)) { struct drm_encoder * encoder = omap_connector_attached_encoder (priv->connectors[j]); if (encoder) { mgr = omap_encoder_get_manager (encoder); } } j++; } /* if we couldn't find another connected connector, lets start looking * at the unconnected connectors: */ while (j < 2 * priv->num_connectors && !mgr) { int idx = j - priv->num_connectors; if (!(connected_connectors & (1 << idx))) { struct drm_encoder * encoder = omap_connector_attached_encoder (priv->connectors[idx]); if (encoder) { mgr = omap_encoder_get_manager (encoder); } } j++; } if (mgr) { DBG("connecting %s to %s", ovl->name, mgr->name); ovl->set_manager(ovl, mgr); } crtc = omap_crtc_init(dev, ovl); if (!crtc) { dev_err(dev->dev, "could not create CRTC\n"); return -ENOMEM; } priv->crtcs[priv->num_crtcs++] = crtc; return 0; } drm_mode_config_init(dev); if (pdata) { /* if platform data is provided by the board file, use it to control * which overlays, managers, and devices we own. */ for (i = 0; i < pdata->mgr_cnt; i++) { if (create_encoder(pdata->mgr_ids[i])) { goto fail; } } for (i = 0; i < pdata->dev_cnt; i++) { int m(struct omap_dss_device *dssdev, void *data) { return ! strcmp(dssdev->name, data); } struct omap_dss_device *dssdev = omap_dss_find_device((void *)pdata->dev_names[i], m); if (!dssdev) { dev_warn(dev->dev, "no such dssdev: %s\n", pdata->dev_names[i]); continue; } if (create_connector(dssdev)) { goto fail; } } j = 0; for (i = 0; i < pdata->ovl_cnt; i++) { if (create_crtc(pdata->ovl_ids[i])) { goto fail; } } } else {