Example #1
0
int mdfld_dsi_dsr_allow(struct mdfld_dsi_config *dsi_config)
{
	int err = 0;

	if (!dsi_config)
		return -EINVAL;

	mutex_lock(&dsi_config->context_lock);

	err = mdfld_dsi_dsr_allow_locked(dsi_config);

	mutex_unlock(&dsi_config->context_lock);

	return err;
}
/**
 * Power off sequence for command mode MIPI panel.
 * NOTE: do NOT modify this function
 */
static int __dbi_panel_power_off(struct mdfld_dsi_config *dsi_config,
			struct panel_funcs *p_funcs)
{
	struct mdfld_dsi_hw_registers *regs;
	struct mdfld_dsi_hw_context *ctx;
	struct drm_device *dev;
	struct drm_psb_private *dev_priv;
	int err = 0;

	if (!dsi_config)
		return -EINVAL;

	PSB_DEBUG_ENTRY("\n");

	regs = &dsi_config->regs;
	ctx = &dsi_config->dsi_hw_context;
	dev = dsi_config->dev;
	dev_priv = dev->dev_private;

	mdfld_dsi_dsr_forbid_locked(dsi_config);
	ctx->lastbrightnesslevel = psb_brightness;
	if (p_funcs && p_funcs->set_brightness)
		if (p_funcs->set_brightness(dsi_config, 0))
			DRM_ERROR("Failed to set panel brightness\n");

	/*wait for two TE, let pending PVR flip complete*/
	msleep(32);

	/**
	 * Different panel may have different ways to have
	 * panel turned off. Support it!
	 */
	if (p_funcs && p_funcs->power_off) {
		if (p_funcs->power_off(dsi_config)) {
			DRM_ERROR("Failed to power off panel\n");
			err = -EAGAIN;
			goto power_off_err;
		}
	}

	/*power off dbi interface*/
	__dbi_power_off(dsi_config);

power_off_err:
	mdfld_dsi_dsr_allow_locked(dsi_config);
	return err;
}
/**
 * Power on sequence for command mode MIPI panel.
 * NOTE: do NOT modify this function
 */
static int __dbi_panel_power_on(struct mdfld_dsi_config *dsi_config,
			struct panel_funcs *p_funcs)
{
	struct mdfld_dsi_hw_registers *regs;
	struct mdfld_dsi_hw_context *ctx;
	struct drm_psb_private *dev_priv;
	struct drm_device *dev;
	int reset_count = 10;
	int err = 0;
	struct mdfld_dsi_pkg_sender *sender
			= mdfld_dsi_get_pkg_sender(dsi_config);
	struct mdfld_dbi_dsr_info *dsr_info;
	struct mdfld_dsi_dbi_output **dbi_outputs;
	struct mdfld_dsi_dbi_output *dbi_output;

	if (!sender) {
		DRM_ERROR("pkg sender is NULL\n");
		return -EINVAL;
	}

	PSB_DEBUG_ENTRY("\n");

	if (!dsi_config)
		return -EINVAL;

	regs = &dsi_config->regs;
	ctx = &dsi_config->dsi_hw_context;
	dev = dsi_config->dev;
	dev_priv = dev->dev_private;

	mdfld_dsi_dsr_forbid_locked(dsi_config);
reset_recovery:
	--reset_count;
	err = 0;
	/*after entering dstb mode, need reset*/
	if (p_funcs && p_funcs->exit_deep_standby)
		p_funcs->exit_deep_standby(dsi_config);

	if (__dbi_power_on(dsi_config)) {
		DRM_ERROR("Failed to init display controller!\n");
		err = -EAGAIN;
		goto power_on_err;
	}

	/**
	 * Different panel may have different ways to have
	 * drvIC initialized. Support it!
	 */
	if (p_funcs && p_funcs->drv_ic_init) {
		if (p_funcs->drv_ic_init(dsi_config)) {
			DRM_ERROR("Failed to init dsi controller!\n");
			err = -EAGAIN;
			goto power_on_err;
		}
	}
	/* Issue "write_mem_start" DSI command during power on. */
	dsr_info = dev_priv->dbi_dsr_info;
	dbi_outputs = dsr_info->dbi_outputs;
	dbi_output = dsi_config->pipe ? dbi_outputs[1] : dbi_outputs[0];

	if (!IS_ANN_A0(dev))
		intel_dsi_dbi_update_fb(dbi_output);

	/**
	 * Different panel may have different ways to have
	 * panel turned on. Support it!
	 */
	if (p_funcs && p_funcs->power_on)
		if (p_funcs->power_on(dsi_config)) {
			DRM_ERROR("Failed to power on panel\n");
			err = -EAGAIN;
			goto power_on_err;
		}
	if (p_funcs && p_funcs->set_brightness)
		if (p_funcs->set_brightness(dsi_config,
					ctx->lastbrightnesslevel))
			DRM_ERROR("Failed to set panel brightness\n");

	/*wait for all FIFOs empty*/
	mdfld_dsi_wait_for_fifos_empty(sender);
	if (is_dual_dsi(dev)) {
		sender->work_for_slave_panel = true;
		mdfld_dsi_wait_for_fifos_empty(sender);
		sender->work_for_slave_panel = false;
	}

	if (IS_ANN_A0(dev))
		intel_dsi_dbi_update_fb(dbi_output);

power_on_err:
	if (err && reset_count) {
		DRM_ERROR("Failed to init panel, try  reset it again!\n");
		goto reset_recovery;
	}
	mdfld_dsi_dsr_allow_locked(dsi_config);
	return err;
}
static ssize_t panel_acl_store(struct device *dev,
			struct device_attribute *attr,
			char *buf, size_t count)
{
	int r = 0;
	struct drm_device *ddev = pci_get_drvdata(to_pci_dev(dev));
	struct drm_psb_private *dev_priv;
	struct mdfld_dsi_config *dsi_config = NULL;
	struct panel_funcs *p_funcs;
	int old_state = mdfld_mot_cmn_acl_mode_get();
	unsigned long new_state;

	if (old_state == ACL_NOT_SUPPORTED) {
		DRM_ERROR("Tried to set ACL, not supported\n");
		r = -EINVAL;
		goto err;
	}

	r = strict_strtoul(buf, 0, &new_state);
	if ((r) || ((new_state != 0) && (new_state != 1))) {
		DRM_ERROR("Invalid ACL value = %lu\n", new_state);
		r = -EINVAL;
		goto err;
	}

	if (!ddev || !ddev->dev_private) {
		DRM_ERROR("Invalid device\n");
		r = -ENODEV;
		goto err;
	}

	dev_priv = ddev->dev_private;
	dsi_config = dev_priv->dsi_configs[0];
	if (!dsi_config) {
		DRM_ERROR("No dsi config when setting ACL\n");
		r = -ENODEV;
		goto err;
	}

	p_funcs = dsi_config_to_p_func(dsi_config);
	if (!p_funcs) {
		DRM_ERROR("No p_funcs when setting ACL\n");
		r = -ENODEV;
		goto err;
	} else if (new_state != old_state) {
		if (ospm_power_using_hw_begin(OSPM_DISPLAY_ISLAND,
						OSPM_UHB_FORCE_POWER_ON)) {
			mutex_lock(&dsi_config->context_lock);
			acl_mode_state = new_state;

			if (dsi_config->dsi_hw_context.panel_on) {
				mdfld_dsi_dsr_forbid_locked(dsi_config);
				r = p_funcs->mot_panel->acl_update(dsi_config);
				mdfld_dsi_dsr_allow_locked(dsi_config);
			}

			mutex_unlock(&dsi_config->context_lock);
			PSB_DEBUG_ENTRY("Updated ACL state to %d\n", new_state);
			ospm_power_using_hw_end(OSPM_DISPLAY_ISLAND);
		} else {
			r = -EAGAIN;
			DRM_ERROR("Failed to enable display island\n");
		}
	}

err:
	return r ? r : count;
}