int dss_ovl_simple_check(struct omap_overlay *ovl,
		const struct omap_overlay_info *info)
{
	if (info->paddr == 0) {
		DSSERR("check_overlay: paddr cannot be 0\n");
		return -EINVAL;
	}

	if ((ovl->caps & OMAP_DSS_OVL_CAP_SCALE) == 0) {
		if (info->out_width != 0 && info->width != info->out_width) {
			DSSERR("check_overlay: overlay %d doesn't support "
					"scaling\n", ovl->id);
			return -EINVAL;
		}

		if (info->out_height != 0 && info->height != info->out_height) {
			DSSERR("check_overlay: overlay %d doesn't support "
					"scaling\n", ovl->id);
			return -EINVAL;
		}
	}

	if ((ovl->supported_modes & info->color_mode) == 0) {
		DSSERR("check_overlay: overlay %d doesn't support mode %d\n",
				ovl->id, info->color_mode);
		return -EINVAL;
	}

	if (info->zorder >= omap_dss_get_num_overlays()) {
		DSSERR("check_overlay: zorder %d too high\n", info->zorder);
		return -EINVAL;
	}

	return 0;
}
Exemple #2
0
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];

}
Exemple #3
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;
}
Exemple #4
0
/*
 * 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);
}
Exemple #6
0
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);
		}
	}
}
Exemple #8
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;
	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);
}
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 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();
}
				goto fail;
			}
		}

		j = 0;
		for (i = 0; i < pdata->ovl_cnt; i++) {
			if (create_crtc(pdata->ovl_ids[i])) {
				goto fail;
			}
		}
	} 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(), CONFIG_DRM_OMAP_NUM_CRTCS);

		for (i = 0; i < omap_dss_get_num_overlay_managers(); i++) {
			if (create_encoder(i)) {
				goto fail;
			}
		}

		for_each_dss_dev(dssdev) {
			if (create_connector(dssdev)) {
				goto fail;
			}
		}

		j = 0;
		for (i = 0; i < max_overlays; i++) {