static void dpst_restore_gamma_settings(struct drm_device *dev)
{
	struct drm_psb_private *dev_priv = dev->dev_private;
	struct mdfld_dsi_config *dsi_config;
	struct mdfld_dsi_hw_context *ctx;
	struct drm_connector *connector;
	struct drm_crtc *crtc;
	struct psb_intel_crtc *psb_intel_crtc;
	int i = 0;

	if (!dev_priv)
		return;

	connector = dev_priv->dpst_lvds_connector;
	dsi_config = dev_priv->dsi_configs[0];
	ctx = &dsi_config->dsi_hw_context;

	crtc = connector->encoder->crtc;
	psb_intel_crtc = to_psb_intel_crtc(crtc);

	if (!ospm_power_using_hw_begin(OSPM_DISPLAY_ISLAND,
				OSPM_UHB_FORCE_POWER_ON))
		return;
	mdfld_dsi_dsr_forbid(dsi_config);

	for (i = 0; i < 256; i++) {
		ctx->palette[i] = lut_adj[i];
		REG_WRITE((PALETTE_A + 4 * i), lut_adj[i]);
	}

	mdfld_dsi_dsr_allow(dsi_config);
	ospm_power_using_hw_end(OSPM_DISPLAY_ISLAND);
}
int psb_update_guard(struct drm_device *dev, void *data)
{
	struct drm_psb_private *dev_priv = psb_priv(dev);
	struct dpst_guardband *input = (struct dpst_guardband *)data;
	struct mdfld_dsi_config *dsi_config = NULL;
	struct mdfld_dsi_hw_context *ctx = NULL;
	struct dpst_guardband reg_data;

	if (!dev_priv)
		return 0;
	dsi_config = dev_priv->dsi_configs[0];
	if (!dsi_config)
		return 0;
	ctx = &dsi_config->dsi_hw_context;

	if (!ospm_power_using_hw_begin
	    (OSPM_DISPLAY_ISLAND, OSPM_UHB_FORCE_POWER_ON))
		return 0;

	mdfld_dsi_dsr_forbid(dsi_config);

	reg_data.data = PSB_RVDC32(HISTOGRAM_INT_CONTROL);
	reg_data.guardband = input->guardband;
	reg_data.guardband_interrupt_delay = input->guardband_interrupt_delay;

	PSB_WVDC32(reg_data.data, HISTOGRAM_INT_CONTROL);
	ctx->histogram_intr_ctrl = reg_data.data;

	mdfld_dsi_dsr_allow(dsi_config);

	ospm_power_using_hw_end(OSPM_DISPLAY_ISLAND);

	return 0;
}
/* SH TODO This doesn't work yet. */
int psb_diet_enable(struct drm_device *dev, void *data)
{
	struct drm_psb_private *dev_priv = psb_priv(dev);
	struct mdfld_dsi_config *dsi_config = NULL;
	struct mdfld_dsi_hw_context *ctx = NULL;
	uint32_t *arg = data;
	struct dpst_ie_histogram_control ie_hist_cont_reg;
	u32 i;
	int dpst3_bin_threshold_count = 1;
	int dpst_hsv_multiplier = 2;
	uint32_t blm_hist_ctl = HISTOGRAM_LOGIC_CONTROL;
	uint32_t iebdr_reg = HISTOGRAM_BIN_DATA;
	int dpst3_bin_count = 32;

	if (!dev_priv)
		return 0;
	dsi_config = dev_priv->dsi_configs[0];
	if (!dsi_config)
		return 0;
	ctx = &dsi_config->dsi_hw_context;

	if (!ospm_power_using_hw_begin
	    (OSPM_DISPLAY_ISLAND, OSPM_UHB_ONLY_IF_ON))
		return 0;

	mdfld_dsi_dsr_forbid(dsi_config);

	if (data) {
		ie_hist_cont_reg.data = PSB_RVDC32(blm_hist_ctl);
		ie_hist_cont_reg.bin_reg_func_select =
		    dpst3_bin_threshold_count;
		ie_hist_cont_reg.bin_reg_index = 0;

		PSB_WVDC32(ie_hist_cont_reg.data, blm_hist_ctl);

		for (i = 0; i < dpst3_bin_count; i++)
			PSB_WVDC32(arg[i], iebdr_reg);
		ctx->aimg_enhance_bin = PSB_RVDC32(iebdr_reg);

		ie_hist_cont_reg.data = PSB_RVDC32(blm_hist_ctl);
		ie_hist_cont_reg.ie_mode_table_enabled = 1;
		ie_hist_cont_reg.alt_enhancement_mode = dpst_hsv_multiplier;

		PSB_WVDC32(ie_hist_cont_reg.data, blm_hist_ctl);
		ctx->histogram_logic_ctrl = ie_hist_cont_reg.data;
	} else {
		ie_hist_cont_reg.data = PSB_RVDC32(blm_hist_ctl);
		ie_hist_cont_reg.ie_mode_table_enabled = 0;

		PSB_WVDC32(ie_hist_cont_reg.data, blm_hist_ctl);
		ctx->histogram_logic_ctrl = ie_hist_cont_reg.data;
	}

	mdfld_dsi_dsr_allow(dsi_config);
	ospm_power_using_hw_end(OSPM_DISPLAY_ISLAND);

	return 0;
}
static int psb_hist_status(struct drm_device *dev, void *data)
{
	struct drm_psb_private *dev_priv = psb_priv(dev);
	struct drm_psb_hist_status_arg *hist_status = data;
	uint32_t *arg = hist_status->buf;
	struct mdfld_dsi_config *dsi_config = NULL;
	u32 iedbr_reg_data = 0;
	struct dpst_ie_histogram_control ie_hist_cont_reg;
	u32 i;
	int dpst3_bin_threshold_count = 0;
	uint32_t blm_hist_ctl = HISTOGRAM_LOGIC_CONTROL;
	uint32_t iebdr_reg = HISTOGRAM_BIN_DATA;
	uint32_t segvalue_max_22_bit = 0x3fffff;
	uint32_t iedbr_busy_bit = 0x80000000;
	int dpst3_bin_count = 32;

	if (!dev_priv)
		return 0;
	dsi_config = dev_priv->dsi_configs[0];
	if (!dsi_config)
		return 0;

	if (!ospm_power_using_hw_begin
	    (OSPM_DISPLAY_ISLAND, OSPM_UHB_FORCE_POWER_ON)) {
		return 0;
	}
	mdfld_dsi_dsr_forbid(dsi_config);

	ie_hist_cont_reg.data = PSB_RVDC32(blm_hist_ctl);
	ie_hist_cont_reg.bin_reg_func_select = dpst3_bin_threshold_count;
	ie_hist_cont_reg.bin_reg_index = 0;

	PSB_WVDC32(ie_hist_cont_reg.data, blm_hist_ctl);

	for (i = 0; i < dpst3_bin_count; i++) {
		iedbr_reg_data = PSB_RVDC32(iebdr_reg);

		if (!(iedbr_reg_data & iedbr_busy_bit)) {
			arg[i] = iedbr_reg_data & segvalue_max_22_bit;
		} else {
			i = 0;
			ie_hist_cont_reg.data = PSB_RVDC32(blm_hist_ctl);
			ie_hist_cont_reg.bin_reg_index = 0;
			PSB_WVDC32(ie_hist_cont_reg.data, blm_hist_ctl);
		}
	}
	mdfld_dsi_dsr_allow(dsi_config);

	ospm_power_using_hw_end(OSPM_DISPLAY_ISLAND);

	return 0;
}
int psb_dpst_mode(struct drm_device *dev, void *data)
{
	struct drm_psb_private *dev_priv = psb_priv(dev);
	struct mdfld_dsi_config *dsi_config = NULL;
	uint32_t *arg = data;
	uint32_t x = 0;
	uint32_t y = 0;
	uint32_t reg;

	if (!dev_priv)
		return 0;

	dsi_config = dev_priv->dsi_configs[0];
	if (!dsi_config)
		return 0;
	mdfld_dsi_dsr_forbid(dsi_config);

	if (!ospm_power_using_hw_begin(OSPM_DISPLAY_ISLAND,
				OSPM_UHB_ONLY_IF_ON))
		return 0;

	reg = PSB_RVDC32(PIPEASRC);

	ospm_power_using_hw_end(OSPM_DISPLAY_ISLAND);

	mdfld_dsi_dsr_allow(dsi_config);
	/* horizontal is the left 16 bits */
	x = reg >> 16;
	/* vertical is the right 16 bits */
	y = reg & 0x0000ffff;

	/* the values are the image size minus one */
	x += 1;
	y += 1;

	*arg = (x << 16) | y;

	return 0;
}
// SH START DIET
int psb_diet_enable(struct drm_device *dev, void *data)
{
	struct drm_psb_private *dev_priv = psb_priv(dev);
	struct mdfld_dsi_config *dsi_config = NULL;
	struct mdfld_dsi_hw_context *ctx = NULL;
	uint32_t * arg = data;
	struct dpst_ie_histogram_control ie_hist_cont_reg;
	u32 i;
	uint32_t blm_hist_ctl = HISTOGRAM_LOGIC_CONTROL;
	uint32_t iebdr_reg = HISTOGRAM_BIN_DATA;
	int dpst3_bin_count = 32;
	 u32 temp =0;

	if (!dev_priv)
		return 0;

	if(dev_priv->early_suspended)
		return 0;

	dsi_config = dev_priv->dsi_configs[0];
	if (!dsi_config)
		return 0;
	ctx = &dsi_config->dsi_hw_context;

	mutex_lock(&dpst_mutex);

	if (power_island_get(OSPM_DISPLAY_A))
	{
		mdfld_dsi_dsr_forbid(dsi_config);
		if (data) {
			ie_hist_cont_reg.data = PSB_RVDC32(blm_hist_ctl);
			dpst_print("hist_ctl: 0x%x\n", ie_hist_cont_reg.data);
			ie_hist_cont_reg.bin_reg_func_select = 1;
			ie_hist_cont_reg.bin_reg_index = 0;
			ie_hist_cont_reg.ie_histogram_enable = 1;
			ie_hist_cont_reg.ie_mode_table_enabled = 1;
			ie_hist_cont_reg.ie_pipe_assignment = 0;
#ifdef HSV
			ie_hist_cont_reg.histogram_mode_select = 1;//HSV
			ie_hist_cont_reg.alt_enhancement_mode = 2;//dpst_hsv_multiplier;
#else
			ie_hist_cont_reg.histogram_mode_select = 0;//YUV
			ie_hist_cont_reg.alt_enhancement_mode = 1; //additive
#endif
			PSB_WVDC32(ie_hist_cont_reg.data, blm_hist_ctl);
			if (drm_psb_debug & PSB_D_DPST) {
				printk("previous corr: ");
				for (i = 0; i <= dpst3_bin_count; i++)
				{
					printk(" 0x%x ", PSB_RVDC32(iebdr_reg));
				}
				printk("\n");
			}
			PSB_WVDC32(0x200, iebdr_reg);
			for (i = 1; i <= dpst3_bin_count; i++)
			{
				PSB_WVDC32(arg[i], iebdr_reg);
			}
			ctx->aimg_enhance_bin = PSB_RVDC32(iebdr_reg);

			ie_hist_cont_reg.data = PSB_RVDC32(blm_hist_ctl);

			temp = ie_hist_cont_reg.data;
			temp|=(1<<27);
			temp&=~0x7f;
			ie_hist_cont_reg.data = temp;
			PSB_WVDC32(ie_hist_cont_reg.data, blm_hist_ctl);

			ctx->histogram_logic_ctrl = ie_hist_cont_reg.data;
		} else {
			ie_hist_cont_reg.data = PSB_RVDC32(blm_hist_ctl);
			ie_hist_cont_reg.ie_mode_table_enabled = 0;
			PSB_WVDC32(ie_hist_cont_reg.data, blm_hist_ctl);
			ctx->histogram_logic_ctrl = ie_hist_cont_reg.data;
		}

		mdfld_dsi_dsr_allow(dsi_config);
		power_island_put(OSPM_DISPLAY_A);
	}

	mutex_unlock(&dpst_mutex);

	return 0;
}
 static int psb_hist_status(struct drm_device *dev, void *data)
{
	struct drm_psb_private *dev_priv = psb_priv(dev);
	struct drm_psb_hist_status_arg *hist_status = data;
	uint32_t * arg = hist_status->buf;
	struct mdfld_dsi_config *dsi_config = NULL;
	u32 iedbr_reg_data = 0;
	struct dpst_ie_histogram_control ie_hist_cont_reg;
	u32 i;
	uint32_t blm_hist_ctl = HISTOGRAM_LOGIC_CONTROL;
	uint32_t iebdr_reg = HISTOGRAM_BIN_DATA;
	uint32_t segvalue_max_22_bit = 0x3fffff;
	uint32_t iedbr_busy_bit = 0x80000000;
	int dpst3_bin_count = 32; //Different DPST Algs has different Values?

	if (!dev_priv)
		return 0;

	dsi_config = dev_priv->dsi_configs[0];
	if (!dsi_config)
		return 0;

	/* Use a fake hist status to avoid enhancement is adapted to black
	 * content during suspend, while make content too bright on resume.
	*/
	if(dev_priv->early_suspended) {
		memcpy(arg, dpst_hist_fake, 32*sizeof(uint32_t));
		return 0;
	}

	mutex_lock(&dpst_mutex);
	/*
	 * FIXME: We need to force the Display to
	 * turn on but on TNG OSPM how we can force PIPEA to do it?
	 */
	if (power_island_get(OSPM_DISPLAY_A))
	{
		mdfld_dsi_dsr_forbid(dsi_config);

		ie_hist_cont_reg.data = PSB_RVDC32(blm_hist_ctl);
		dpst_print("hist_ctl: 0x%x\n", ie_hist_cont_reg.data);
		ie_hist_cont_reg.bin_reg_func_select = 0;
		ie_hist_cont_reg.bin_reg_index = 0;
		ie_hist_cont_reg.ie_histogram_enable = 1;
		ie_hist_cont_reg.ie_mode_table_enabled = 1;
		ie_hist_cont_reg.ie_pipe_assignment = 0;
#ifdef HSV
		ie_hist_cont_reg.histogram_mode_select = 1;//HSV
		ie_hist_cont_reg.alt_enhancement_mode = 2;//dpst_hsv_multiplier;
#else
		ie_hist_cont_reg.histogram_mode_select = 0;//YUV
		ie_hist_cont_reg.alt_enhancement_mode = 1; //additive
#endif

		PSB_WVDC32(ie_hist_cont_reg.data, blm_hist_ctl);
		dpst_print("hist static: \n");
		for (i = 0; i < dpst3_bin_count; i++) {
			iedbr_reg_data = PSB_RVDC32(iebdr_reg);
			if (!(iedbr_reg_data & iedbr_busy_bit)) {
				arg[i] = iedbr_reg_data & segvalue_max_22_bit;
				dpst_print("hist_ctl 0x%d 0x%x\n", 0x3ff & PSB_RVDC32(blm_hist_ctl), arg[i]);
			} else {
				i = -1;
				ie_hist_cont_reg.data = PSB_RVDC32(blm_hist_ctl);
				ie_hist_cont_reg.bin_reg_index = 0;
				PSB_WVDC32(ie_hist_cont_reg.data, blm_hist_ctl);
			}
		}
		mdfld_dsi_dsr_allow(dsi_config);
		power_island_put(OSPM_DISPLAY_A);
	}

	mutex_unlock(&dpst_mutex);

	return 0;
}
/* IOCTL - moved to standard calls for Kernel Integration */
int psb_hist_enable(struct drm_device *dev, void *data)
{
	struct drm_psb_private *dev_priv = psb_priv(dev);
	struct dpst_guardband guardband_reg;
	struct dpst_ie_histogram_control ie_hist_cont_reg;
	struct mdfld_dsi_hw_context *ctx = NULL;
	uint32_t * enable = data;
	struct mdfld_dsi_config *dsi_config = NULL;

	if (!dev_priv)
		return 0;

	dsi_config = dev_priv->dsi_configs[0];
	if(!dsi_config)
		return 0;
	ctx = &dsi_config->dsi_hw_context;

	mutex_lock(&dpst_mutex);
	/*
	* FIXME: We need to force the Display to
	* turn on but on TNG OSPM how we can force PIPEA to do it?
	*/
	if (power_island_get(OSPM_DISPLAY_A)) {

		mdfld_dsi_dsr_forbid(dsi_config);

		if (*enable == 1) {
			ie_hist_cont_reg.data = PSB_RVDC32(HISTOGRAM_LOGIC_CONTROL);
			ie_hist_cont_reg.ie_pipe_assignment = 0;
			ie_hist_cont_reg.bin_reg_func_select = 1;
			ie_hist_cont_reg.bin_reg_index = 0;
			ie_hist_cont_reg.ie_histogram_enable = 1;
			ie_hist_cont_reg.ie_mode_table_enabled = 1;
#ifdef HSV
			ie_hist_cont_reg.histogram_mode_select = 1;//HSV
			ie_hist_cont_reg.alt_enhancement_mode = 2;//dpst_hsv_multiplier;
#else
			ie_hist_cont_reg.histogram_mode_select = 0;//YUV
			ie_hist_cont_reg.alt_enhancement_mode = 1; //additive
#endif
			PSB_WVDC32(ie_hist_cont_reg.data, HISTOGRAM_LOGIC_CONTROL);
			ctx->histogram_logic_ctrl = ie_hist_cont_reg.data;
			dpst_print("hist_ctl 0x%x\n", ie_hist_cont_reg.data);

			guardband_reg.data = PSB_RVDC32(HISTOGRAM_INT_CONTROL);
			guardband_reg.interrupt_enable = 1;
			guardband_reg.interrupt_status = 1;

			PSB_WVDC32(guardband_reg.data, HISTOGRAM_INT_CONTROL);
			ctx->histogram_intr_ctrl = guardband_reg.data;
			dpst_print("guardband 0x%x\n", guardband_reg.data);

			/* Wait for two vblanks */
		} else {
			guardband_reg.data = PSB_RVDC32(HISTOGRAM_INT_CONTROL);
			guardband_reg.interrupt_enable = 0;
			guardband_reg.interrupt_status = 1;
			PSB_WVDC32(guardband_reg.data, HISTOGRAM_INT_CONTROL);
			ctx->histogram_intr_ctrl = guardband_reg.data;
			dpst_print("guardband 0x%x\n", guardband_reg.data);

			ie_hist_cont_reg.data = PSB_RVDC32(HISTOGRAM_LOGIC_CONTROL);
			ie_hist_cont_reg.ie_histogram_enable = 0;
			PSB_WVDC32(ie_hist_cont_reg.data, HISTOGRAM_LOGIC_CONTROL);
			ctx->histogram_logic_ctrl = ie_hist_cont_reg.data;
			dpst_print("disabled: hist_ctl 0x%x\n", ie_hist_cont_reg.data);

			dpst_disable_post_process(g_dev);
		}

		mdfld_dsi_dsr_allow(dsi_config);
		power_island_put(OSPM_DISPLAY_A);
	}

	mutex_unlock(&dpst_mutex);

	return 0;
}
int psb_hist_enable(struct drm_device *dev, void *data)
{
	u32 irqCtrl = 0;
	struct drm_psb_private *dev_priv = psb_priv(dev);
	struct dpst_guardband guardband_reg;
	struct dpst_ie_histogram_control ie_hist_cont_reg;
	struct mdfld_dsi_hw_context *ctx = NULL;
	uint32_t *enable = data;
	struct mdfld_dsi_config *dsi_config = NULL;

	if (!dev_priv)
		return 0;
	dsi_config = dev_priv->dsi_configs[0];
	if (!dsi_config)
		return 0;
	ctx = &dsi_config->dsi_hw_context;

	if (!ospm_power_using_hw_begin
	    (OSPM_DISPLAY_ISLAND, OSPM_UHB_FORCE_POWER_ON)) {
		return 0;
	}
	mdfld_dsi_dsr_forbid(dsi_config);

	if (*enable == 1) {
		ie_hist_cont_reg.data = PSB_RVDC32(HISTOGRAM_LOGIC_CONTROL);
		ie_hist_cont_reg.ie_pipe_assignment = 0;
		ie_hist_cont_reg.histogram_mode_select = DPST_YUV_LUMA_MODE;
		ie_hist_cont_reg.ie_histogram_enable = 1;
		PSB_WVDC32(ie_hist_cont_reg.data, HISTOGRAM_LOGIC_CONTROL);
		ctx->histogram_logic_ctrl = ie_hist_cont_reg.data;

		guardband_reg.data = PSB_RVDC32(HISTOGRAM_INT_CONTROL);
		guardband_reg.interrupt_enable = 1;
		guardband_reg.interrupt_status = 1;
		PSB_WVDC32(guardband_reg.data, HISTOGRAM_INT_CONTROL);
		ctx->histogram_intr_ctrl = guardband_reg.data;

		irqCtrl = PSB_RVDC32(PIPEASTAT);
		ctx->pipestat = (irqCtrl | PIPE_DPST_EVENT_ENABLE);
		PSB_WVDC32(ctx->pipestat, PIPEASTAT);
	} else {
		guardband_reg.data = PSB_RVDC32(HISTOGRAM_INT_CONTROL);
		guardband_reg.interrupt_enable = 0;
		guardband_reg.interrupt_status = 1;
		PSB_WVDC32(guardband_reg.data, HISTOGRAM_INT_CONTROL);
		ctx->histogram_intr_ctrl = guardband_reg.data;

		ie_hist_cont_reg.data = PSB_RVDC32(HISTOGRAM_LOGIC_CONTROL);
		ie_hist_cont_reg.ie_histogram_enable = 0;
		PSB_WVDC32(ie_hist_cont_reg.data, HISTOGRAM_LOGIC_CONTROL);
		ctx->histogram_logic_ctrl = ie_hist_cont_reg.data;

		irqCtrl = PSB_RVDC32(PIPEASTAT);
		irqCtrl &= ~PIPE_DPST_EVENT_ENABLE;
		PSB_WVDC32(irqCtrl, PIPEASTAT);
		ctx->pipestat = irqCtrl;
		dpst_disable_post_process(g_dev);
	}

	mdfld_dsi_dsr_allow(dsi_config);
	ospm_power_using_hw_end(OSPM_DISPLAY_ISLAND);

	return 0;
}