From: Li Peng Date: Sat, 28 Apr 2012 15:50:29 +0000 (+0800) Subject: TMD 6x10: merge MCG display panel code onto OTC pvr driver X-Git-Tag: 2.1b_release~170 X-Git-Url: http://review.tizen.org/git/?a=commitdiff_plain;h=6fdc3423d2faad41aa65c21104ecf6b1605681ed;p=kernel%2Fkernel-mfld-blackbay.git TMD 6x10: merge MCG display panel code onto OTC pvr driver The purpose is to pull latest MCG display panel code into OTC pvr driver. This commit creates symbol link to MCG source files including mdfld_dsi_dbi{dpi}, mdfld_output and mdfld_dsi_pkg_sender, etc. Signed-off-by: Li Peng Signed-off-by: Markus Lehtonen --- diff --git a/drivers/staging/mrst/drv/displays/tmd_6x10_vid.h b/drivers/staging/mrst/drv/displays/tmd_6x10_vid.h new file mode 120000 index 0000000..65e0242 --- /dev/null +++ b/drivers/staging/mrst/drv/displays/tmd_6x10_vid.h @@ -0,0 +1 @@ +../../../mrst.mcg/drv/displays/tmd_6x10_vid.h \ No newline at end of file diff --git a/drivers/staging/mrst/drv/mdfld_csc.h b/drivers/staging/mrst/drv/mdfld_csc.h new file mode 120000 index 0000000..6320b18 --- /dev/null +++ b/drivers/staging/mrst/drv/mdfld_csc.h @@ -0,0 +1 @@ +../../mrst.mcg/drv/mdfld_csc.h \ No newline at end of file diff --git a/drivers/staging/mrst/drv/mdfld_dsi_dbi.c b/drivers/staging/mrst/drv/mdfld_dsi_dbi.c deleted file mode 100644 index cd1f725..0000000 --- a/drivers/staging/mrst/drv/mdfld_dsi_dbi.c +++ /dev/null @@ -1,706 +0,0 @@ -/* - * Copyright © 2010 Intel Corporation - * - * Permission is hereby granted, free of charge, to any person obtaining a - * copy of this software and associated documentation files (the "Software"), - * to deal in the Software without restriction, including without limitation - * the rights to use, copy, modify, merge, publish, distribute, sublicense, - * and/or sell copies of the Software, and to permit persons to whom the - * Software is furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice (including the next - * paragraph) shall be included in all copies or substantial portions of the - * Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL - * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING - * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER - * DEALINGS IN THE SOFTWARE. - * - * Authors: - * jim liu - * Jackie Li - */ - -#include "mdfld_dsi_dbi.h" -#include "mdfld_dsi_dbi_dpu.h" -#include "mdfld_dsi_pkg_sender.h" - -#include "psb_powermgmt.h" - -static int enter_dsr; -struct mdfld_dsi_dbi_output *gdbi_output; - -#define MDFLD_DSR_MAX_IDLE_COUNT 2 -#define MDFLD_DSI_MAX_RETURN_PACKET_SIZE 512 - -/** - * set refreshing area - */ -int mdfld_dsi_dbi_update_area(struct mdfld_dsi_dbi_output * dbi_output, - u16 x1, u16 y1, u16 x2, u16 y2) -{ - struct mdfld_dsi_pkg_sender * sender = - mdfld_dsi_encoder_get_pkg_sender(&dbi_output->base); - u8 param[5]; - int err; - - if(!sender) { - DRM_ERROR("Cannot get PKG sender\n"); - return -EINVAL; - } - - /*set column*/ - param[0] = DCS_SET_COLUMN_ADDRESS; - param[1] = x1 >> 8; - param[2] = x1; - param[3] = x2 >> 8; - param[4] = x2; - - err = mdfld_dsi_send_mcs_long(sender, param, 5, true); - if(err) { - DRM_ERROR("DCS_SET_COLUMN_ADDRESS sent failed\n"); - goto err_out; - } - - /*set page*/ - param[0] = DCS_SET_PAGE_ADDRESS; - param[1] = y1 >> 8; - param[2] = y1; - param[3] = y2 >> 8; - param[4] = y2; - - err = mdfld_dsi_send_mcs_long(sender, param, 5, true); - if(err) { - DRM_ERROR("DCS_SET_PAGE_ADDRESS sent failed\n"); - goto err_out; - } - - /*update screen*/ - err = mdfld_dsi_write_mem_start(sender); - if(err) { - DRM_ERROR("DCS_WRITE_MEM_START sent failed\n"); - goto err_out; - } - -err_out: - return err; -} - -/** - * set panel's power state - */ -int mdfld_dsi_dbi_update_power(struct mdfld_dsi_dbi_output * dbi_output, int mode) -{ - struct drm_device * dev = dbi_output->dev; - struct drm_psb_private * dev_priv = dev->dev_private; - struct mdfld_dsi_pkg_sender * sender = - mdfld_dsi_encoder_get_pkg_sender(&dbi_output->base); - u32 err = 0; - - if(!sender) { - DRM_ERROR("Cannot get PKG sender\n"); - return -EINVAL; - } - - if(mode == DRM_MODE_DPMS_ON) { - /*exit sleep mode*/ - err = mdfld_dsi_send_mcs_short(sender, DCS_EXIT_SLEEP_MODE, - 0, 0, true); - if (err) { - DRM_ERROR("DCS 0x%x sent failed\n", - DCS_EXIT_SLEEP_MODE); - goto power_err; - } - - /*set display on*/ - err = mdfld_dsi_send_mcs_short(sender, DCS_SET_DISPLAY_ON, - 0, 0, true); - if (err) { - DRM_ERROR("DCS 0x%x sent failed\n", - DCS_SET_DISPLAY_ON); - goto power_err; - } - - /* set tear effect on */ - err = mdfld_dsi_send_mcs_short(sender, DCS_SET_TEAR_ON, - 0, 1, true); - if (err) { - DRM_ERROR("DCS 0x%x sent failed\n", DCS_SET_TEAR_ON); - goto power_err; - } - - /** - * FIXME: remove this later - */ - err = mdfld_dsi_write_mem_start(sender); - if (err) { - DRM_ERROR("DCS 0x%x sent failed\n", - DCS_WRITE_MEM_START); - goto power_err; - } - } else { - /*set tear effect off */ - err = mdfld_dsi_send_mcs_short(sender, DCS_SET_TEAR_OFF, - 0, 0, true); - if (err) { - DRM_ERROR("DCS 0x%x sent failed\n", set_tear_off); - goto power_err; - } - - /*set display off*/ - err = mdfld_dsi_send_mcs_short(sender, DCS_SET_DISPLAY_OFF, - 0, 0, true); - if (err) { - DRM_ERROR("DCS 0x%x sent failed\n", - DCS_SET_DISPLAY_OFF); - goto power_err; - } - - /*enter sleep mode*/ - err = mdfld_dsi_send_mcs_short(sender, DCS_ENTER_SLEEP_MODE, - 0, 0, true); - if (err) { - DRM_ERROR("DCS 0x%x sent failed\n", - DCS_ENTER_SLEEP_MODE); - goto power_err; - } - } - -power_err: - return err; -} - -/** - * Enter DSR - */ -void mdfld_dsi_dbi_enter_dsr (struct mdfld_dsi_dbi_output * dbi_output, int pipe) -{ - u32 reg_val; - struct drm_device * dev = dbi_output->dev; - struct drm_psb_private * dev_priv = dev->dev_private; - struct drm_crtc * crtc = dbi_output->base.base.crtc; - struct psb_intel_crtc * psb_crtc = (crtc) ? to_psb_intel_crtc(crtc) : NULL; - u32 dpll_reg = PSB_DSI_PLL_CTRL; - u32 pipeconf_reg = PSB_PIPECONF(PSB_PIPE_A); - u32 dspcntr_reg = PSB_DSPCNTR(PSB_PIPE_A); - u32 dspbase_reg = PSB_DSPBASE(PSB_PIPE_A); - u32 dspsurf_reg = PSB_DSPSURF(PSB_PIPE_A); - - PSB_DEBUG_ENTRY(" \n"); - - if(!dbi_output) - return; - - gdbi_output = dbi_output; - if((dbi_output->mode_flags & MODE_SETTING_ON_GOING) || - (psb_crtc && psb_crtc->mode_flags & MODE_SETTING_ON_GOING)) - return; - - if(pipe == 2) { - dpll_reg = PSB_DSI_PLL_CTRL; - pipeconf_reg = PSB_PIPECONF(PSB_PIPE_C); - dspcntr_reg = PSB_DSPCNTR(PSB_PIPE_C); - dspbase_reg = PSB_DSPBASE(PSB_PIPE_C); - dspsurf_reg = PSB_DSPSURF(PSB_PIPE_C); - } - - if (!ospm_power_using_hw_begin(OSPM_DISPLAY_ISLAND, true)) { - DRM_ERROR("hw begin failed\n"); - return; - } - - /*disable te interrupts. */ - mdfld_disable_te(dev, pipe); - - /*disable plane*/ - reg_val = REG_READ(dspcntr_reg); - if(!(reg_val & DISPLAY_PLANE_ENABLE)) { - REG_WRITE(dspcntr_reg, reg_val & ~DISPLAY_PLANE_ENABLE); - REG_READ(dspcntr_reg); - } - - /*disable pipe*/ - reg_val = REG_READ(pipeconf_reg); - if(!(reg_val & DISPLAY_PLANE_ENABLE)) { - reg_val &= ~DISPLAY_PLANE_ENABLE; - reg_val |= (PIPECONF_PLANE_OFF | PIPECONF_CURSOR_OFF); - REG_WRITE(pipeconf_reg, reg_val); - REG_READ(pipeconf_reg); - mdfldWaitForPipeDisable(dev, pipe); - } - - /*disable DPLL*/ - reg_val = REG_READ(dpll_reg); - if(!(reg_val & DPLL_VCO_ENABLE)) { - reg_val &= ~DPLL_VCO_ENABLE; - REG_WRITE(dpll_reg, reg_val); - REG_READ(dpll_reg); - udelay(500); - } - - /*gate power of DSI DPLL*/ - ospm_power_using_hw_end(OSPM_DISPLAY_ISLAND); - - /*update mode state to IN_DSR*/ - dbi_output->mode_flags |= MODE_SETTING_IN_DSR; - - if (pipe == 2) - enter_dsr = 1; -} - -#ifndef CONFIG_MDFLD_DSI_DPU -static void mdfld_dbi_output_exit_dsr (struct mdfld_dsi_dbi_output * dbi_output, int pipe) -{ - struct drm_device * dev = dbi_output->dev; - struct drm_psb_private *dev_priv = dev->dev_private; - struct drm_crtc * crtc = dbi_output->base.base.crtc; - struct psb_intel_crtc * psb_crtc = (crtc) ? to_psb_intel_crtc(crtc) : NULL; - u32 reg_val; - u32 dpll_reg = PSB_DSI_PLL_CTRL; - u32 pipeconf_reg = PSB_PIPECONF(PSB_PIPE_A); - u32 dspcntr_reg = PSB_DSPCNTR(PSB_PIPE_A); - - /*if mode setting on-going, back off*/ - if((dbi_output->mode_flags & MODE_SETTING_ON_GOING) || - (psb_crtc && psb_crtc->mode_flags & MODE_SETTING_ON_GOING)) - return; - - if(pipe == 2) { - dpll_reg = PSB_DSI_PLL_CTRL; - pipeconf_reg = PSB_PIPECONF(PSB_PIPE_C); - dspcntr_reg = PSB_DSPCNTR(PSB_PIPE_C); - } - - if (!ospm_power_using_hw_begin(OSPM_DISPLAY_ISLAND, true)) { - DRM_ERROR("hw begin failed\n"); - return; - } - - /*enable DPLL*/ - reg_val = REG_READ(dpll_reg); - if(!(reg_val & DPLL_VCO_ENABLE)) { - - if(reg_val & MDFLD_PWR_GATE_EN) { - reg_val &= ~MDFLD_PWR_GATE_EN; - REG_WRITE(dpll_reg, reg_val); - REG_READ(dpll_reg); - udelay(500); - } - - reg_val |= DPLL_VCO_ENABLE; - REG_WRITE(dpll_reg, reg_val); - REG_READ(dpll_reg); - udelay(500); - - /*add timeout*/ - while (!(REG_READ(pipeconf_reg) & PIPECONF_DSIPLL_LOCK)) { - cpu_relax(); - } - } - - /*enable pipe*/ - reg_val = REG_READ(pipeconf_reg); - if(!(reg_val & PIPEACONF_ENABLE)) { - reg_val |= PIPEACONF_ENABLE; - REG_WRITE(pipeconf_reg, reg_val); - REG_READ(pipeconf_reg); - udelay(500); - mdfldWaitForPipeEnable(dev, pipe); - } - - /*enable plane*/ - reg_val = REG_READ(dspcntr_reg); - if(!(reg_val & DISPLAY_PLANE_ENABLE)) { - reg_val |= DISPLAY_PLANE_ENABLE; - REG_WRITE(dspcntr_reg, reg_val); - REG_READ(dspcntr_reg); - udelay(500); - } - - /*enable TE interrupt on this pipe*/ - mdfld_enable_te(dev, pipe); - - ospm_power_using_hw_end(OSPM_DISPLAY_ISLAND); - - /*clean IN_DSR flag*/ - dbi_output->mode_flags &= ~MODE_SETTING_IN_DSR; -} - -/** - * Exit from DSR - */ -void mdfld_dsi_dbi_exit_dsr(struct drm_device *dev, u32 update_src) -{ - struct drm_psb_private *dev_priv = dev->dev_private; - struct mdfld_dbi_dsr_info * dsr_info = dev_priv->dbi_dsr_info; - struct mdfld_dsi_dbi_output ** dbi_output; - int i; - int pipe; - - PSB_DEBUG_ENTRY("\n"); - - dbi_output = dsr_info->dbi_outputs; - - /*for each output, exit dsr*/ - for(i=0; idbi_output_num; i++) { - /*if panel has been turned off, skip*/ - if (!dbi_output[i] || !dbi_output[i]->dbi_panel_on) - continue; - - pipe = dbi_output[i]->channel_num ? 2 : 0; - enter_dsr = 0; - mdfld_dbi_output_exit_dsr(dbi_output[i], pipe); - } - - dev_priv->dsr_fb_update |= update_src; -} - -static bool mdfld_dbi_is_in_dsr(struct drm_device * dev) -{ - if (REG_READ(PSB_DSI_PLL_CTRL) & DPLL_VCO_ENABLE) - return false; - if ((REG_READ(PSB_PIPECONF(PSB_PIPE_A)) & PIPEACONF_ENABLE) || - (REG_READ(PSB_PIPECONF(PSB_PIPE_C)) & PIPEACONF_ENABLE)) - return false; - if ((REG_READ(PSB_DSPCNTR(PSB_PIPE_A)) & DISPLAY_PLANE_ENABLE) || - (REG_READ(PSB_DSPCNTR(PSB_PIPE_C)) & DISPLAY_PLANE_ENABLE)) - return false; - - return true; -} - -/* Perodically update dbi panel */ -void mdfld_dbi_update_panel (struct drm_device *dev, int pipe) -{ - struct drm_psb_private *dev_priv = dev->dev_private; - struct mdfld_dbi_dsr_info *dsr_info = dev_priv->dbi_dsr_info; - struct mdfld_dsi_dbi_output **dbi_outputs; - struct mdfld_dsi_dbi_output *dbi_output; - int i; - int can_enter_dsr = 0; - int enter_dsr = 0; - u32 damage_mask = 0; - - dbi_outputs = dsr_info->dbi_outputs; - dbi_output = pipe ? dbi_outputs[1] : dbi_outputs[0]; - - if (!dbi_output) - return; - - if (pipe == 0) - damage_mask = dev_priv->dsr_fb_update & MDFLD_DSR_DAMAGE_MASK_0; - else if (pipe == 2) - damage_mask = dev_priv->dsr_fb_update & MDFLD_DSR_DAMAGE_MASK_2; - else - return; - - /*if FB is damaged and panel is on update on-panel FB*/ - if (damage_mask && dbi_output->dbi_panel_on) { - dbi_output->dsr_fb_update_done = false; - - if (dbi_output->p_funcs->update_fb) - dbi_output->p_funcs->update_fb(dbi_output, pipe); - - if (dev_priv->b_dsr_enable && dbi_output->dsr_fb_update_done) - dev_priv->dsr_fb_update &= ~damage_mask; - - /*clean IN_DSR flag*/ - dbi_output->mode_flags &= ~MODE_SETTING_IN_DSR; - - dbi_output->dsr_idle_count = 0; - - } else { - dbi_output->dsr_idle_count++; - } - - switch (dsr_info->dbi_output_num) { - case 1: - if (dbi_output->dsr_idle_count > MDFLD_DSR_MAX_IDLE_COUNT) - can_enter_dsr = 1; - break; - case 2: - if (dbi_outputs[0]->dsr_idle_count > MDFLD_DSR_MAX_IDLE_COUNT - && dbi_outputs[1]->dsr_idle_count > MDFLD_DSR_MAX_IDLE_COUNT) - can_enter_dsr = 1; - break; - default: - DRM_ERROR("Wrong DBI output number\n"); - can_enter_dsr = 0; - } - - /*try to enter DSR*/ - if (can_enter_dsr) { - for(i=0; idbi_output_num; i++) { - if (!mdfld_dbi_is_in_dsr(dev) && dbi_outputs[i] && - !(dbi_outputs[i]->mode_flags & MODE_SETTING_ON_GOING)) { - mdfld_dsi_dbi_enter_dsr(dbi_outputs[i], - dbi_outputs[i]->channel_num ? 2 : 0); -#if 0 - enter_dsr = 1; - printk(KERN_ALERT "%s: enter_dsr = 1 \n", __func__); -#endif - } - } - } -} - -int mdfld_dbi_dsr_init(struct drm_device * dev) -{ - struct drm_psb_private * dev_priv = dev->dev_private; - struct mdfld_dbi_dsr_info * dsr_info = dev_priv->dbi_dsr_info; - - if(!dsr_info || IS_ERR(dsr_info)) { - dsr_info = kzalloc(sizeof(struct mdfld_dbi_dsr_info), GFP_KERNEL); - if(!dsr_info) { - DRM_ERROR("No memory\n"); - return -ENOMEM; - } - - dev_priv->dbi_dsr_info = dsr_info; - } - - PSB_DEBUG_ENTRY("successfully\n"); - - return 0; -} - -void mdfld_dbi_dsr_exit(struct drm_device * dev) -{ - struct drm_psb_private * dev_priv = dev->dev_private; - struct mdfld_dbi_dsr_info * dsr_info = dev_priv->dbi_dsr_info; - - if(!dsr_info) { - return; - } - - /*free dsr info*/ - kfree(dsr_info); - - dev_priv->dbi_dsr_info = NULL; -} -#endif - -void mdfld_dsi_controller_dbi_init(struct mdfld_dsi_config * dsi_config, int pipe) -{ - struct drm_device * dev = dsi_config->dev; - int lane_count = dsi_config->lane_count; - u32 val = 0; - - PSB_DEBUG_ENTRY("Init DBI interface on pipe %d...\n", pipe); - - /*un-ready device*/ - REG_WRITE(MIPI_DEVICE_READY_REG(pipe), 0x00000000); - - /*init dsi adapter before kicking off*/ - REG_WRITE(MIPI_CTRL_REG(pipe), 0x00000018); - - /*TODO: figure out how to setup these registers*/ - REG_WRITE(MIPI_DPHY_PARAM_REG(pipe), 0x150c3408); - REG_WRITE(MIPI_CLK_LANE_SWITCH_TIME_CNT_REG(pipe), 0x000a0014); - REG_WRITE(MIPI_DBI_BW_CTRL_REG(pipe), 0x00000400); - REG_WRITE(MIPI_DBI_FIFO_THROTTLE_REG(pipe), 0x00000001); - REG_WRITE(MIPI_HS_LS_DBI_ENABLE_REG(pipe), 0x00000000); - - /*enable all interrupts*/ - REG_WRITE(MIPI_INTR_EN_REG(pipe), 0xffffffff); - /*max value: 20 clock cycles of txclkesc*/ - REG_WRITE(MIPI_TURN_AROUND_TIMEOUT_REG(pipe), 0x0000001f); - /*min 21 txclkesc, max: ffffh*/ - REG_WRITE(MIPI_DEVICE_RESET_TIMER_REG(pipe), 0x0000ffff); - /*min: 7d0 max: 4e20*/ - REG_WRITE(MIPI_INIT_COUNT_REG(pipe), 0x00000fa0); - - /* set up max return packet size */ - REG_WRITE(MIPI_MAX_RETURN_PACK_SIZE_REG(pipe), - MDFLD_DSI_MAX_RETURN_PACKET_SIZE); - - /*set up func_prg*/ - val |= lane_count; - val |= (dsi_config->channel_num << DSI_DBI_VIRT_CHANNEL_OFFSET); - val |= DSI_DBI_COLOR_FORMAT_OPTION2; - REG_WRITE(MIPI_DSI_FUNC_PRG_REG(pipe), val); - - REG_WRITE(MIPI_HS_TX_TIMEOUT_REG(pipe), 0x3fffff); - REG_WRITE(MIPI_LP_RX_TIMEOUT_REG(pipe), 0xffff); - - /*de-assert dbi_stall when half of DBI FIFO is empty*/ - //REG_WRITE((MIPIA_DBI_FIFO_THROTTLE_REG + reg_offset), 0x00000000); - - REG_WRITE(MIPI_HIGH_LOW_SWITCH_COUNT_REG(pipe), 0x46); - REG_WRITE(MIPI_EOT_DISABLE_REG(pipe), 0x00000000); - REG_WRITE(MIPI_LP_BYTECLK_REG(pipe), 0x00000004); - REG_WRITE(MIPI_DEVICE_READY_REG(pipe), 0x00000001); -} - -#if 0 -/*DBI encoder helper funcs*/ -static const struct drm_encoder_helper_funcs mdfld_dsi_dbi_helper_funcs = { - .dpms = mdfld_dsi_dbi_dpms, - .mode_fixup = mdfld_dsi_dbi_mode_fixup, - .prepare = mdfld_dsi_dbi_prepare, - .mode_set = mdfld_dsi_dbi_mode_set, - .commit = mdfld_dsi_dbi_commit, -}; - -/*DBI encoder funcs*/ -static const struct drm_encoder_funcs mdfld_dsi_dbi_encoder_funcs = { - .destroy = drm_encoder_cleanup, -}; - -#endif - -/* - * Init DSI DBI encoder. - * Allocate an mdfld_dsi_encoder and attach it to given @dsi_connector - * return pointer of newly allocated DBI encoder, NULL on error - */ -struct mdfld_dsi_encoder * mdfld_dsi_dbi_init(struct drm_device * dev, - struct mdfld_dsi_connector * dsi_connector, - struct panel_funcs* p_funcs) -{ - struct drm_psb_private * dev_priv = (struct drm_psb_private *)dev->dev_private; - struct mdfld_dsi_dbi_output * dbi_output = NULL; - struct mdfld_dsi_config * dsi_config; - struct drm_connector * connector = NULL; - struct drm_encoder * encoder = NULL; - struct drm_display_mode * fixed_mode = NULL; - struct psb_gtt * pg = dev_priv ? (dev_priv->pg) : NULL; - -#ifdef CONFIG_MDFLD_DSI_DPU - struct mdfld_dbi_dpu_info * dpu_info = dev_priv ? (dev_priv->dbi_dpu_info) : NULL; -#else - struct mdfld_dbi_dsr_info * dsr_info = dev_priv ? (dev_priv->dbi_dsr_info) : NULL; -#endif - u32 data = 0; - int pipe; - int ret; - - PSB_DEBUG_ENTRY("\n"); - - if (!pg || !dsi_connector || !p_funcs) { - DRM_ERROR("Invalid parameters\n"); - return NULL; - } - - dsi_config = mdfld_dsi_get_config(dsi_connector); - pipe = dsi_connector->pipe; - - /*panel hard-reset*/ - if (p_funcs->reset) { - ret = p_funcs->reset(pipe); - if (ret) { - DRM_ERROR("Panel %d hard-reset failed\n", pipe); - return NULL; - } - } - - /*panel drvIC init*/ - if (p_funcs->drv_ic_init) - p_funcs->drv_ic_init(dsi_config, pipe); - - /*panel power mode detect*/ - ret = mdfld_dsi_get_power_mode(dsi_config, &data, true); - if (ret) { - DRM_ERROR("Panel %d get power mode failed\n", pipe); - - dsi_connector->status = connector_status_disconnected; - } else { - DRM_INFO("pipe %d power mode 0x%x\n", pipe, data); - - dsi_connector->status = connector_status_connected; - } - - /*TODO: get panel info from DDB*/ - - dbi_output = kzalloc(sizeof(struct mdfld_dsi_dbi_output), GFP_KERNEL); - if(!dbi_output) { - DRM_ERROR("No memory\n"); - return NULL; - } - - if(dsi_connector->pipe == 0) { - dbi_output->channel_num = 0; - dev_priv->dbi_output = dbi_output; - } else if (dsi_connector->pipe == 2) { - dbi_output->channel_num = 1; - dev_priv->dbi_output2 = dbi_output; - } else { - DRM_ERROR("only support 2 DSI outputs\n"); - goto out_err1; - } - - dbi_output->dev = dev; - dbi_output->p_funcs = p_funcs; - - /*get fixed mode*/ - fixed_mode = dsi_config->fixed_mode; - - dbi_output->panel_fixed_mode = fixed_mode; - - /*create drm encoder object*/ - connector = &dsi_connector->base.base; - encoder = &dbi_output->base.base; - drm_encoder_init(dev, - encoder, - p_funcs->encoder_funcs, - DRM_MODE_ENCODER_LVDS); - drm_encoder_helper_add( encoder, - p_funcs->encoder_helper_funcs); - - /*attach to given connector*/ - drm_mode_connector_attach_encoder(connector, encoder); - - /*set possible crtcs and clones*/ - if(dsi_connector->pipe) { - encoder->possible_crtcs = (1 << 2); - encoder->possible_clones = (1 << 1); - } else { - encoder->possible_crtcs = (1 << 0); - encoder->possible_clones = (1 << 0); - } - - dev_priv->dsr_fb_update = 0; - dev_priv->b_dsr_enable = false; - - dbi_output->first_boot = true; - dbi_output->mode_flags = MODE_SETTING_IN_ENCODER; - -#ifdef CONFIG_MDFLD_DSI_DPU - /*add this output to dpu_info*/ - - if (dsi_connector->status == connector_status_connected) { - if (dsi_connector->pipe == 0) - dpu_info->dbi_outputs[0] = dbi_output; - else - dpu_info->dbi_outputs[1] = dbi_output; - - dpu_info->dbi_output_num++; - } - -#else /*CONFIG_MDFLD_DSI_DPU*/ - if (dsi_connector->status == connector_status_connected) { - /*add this output to dsr_info*/ - if (dsi_connector->pipe == 0) - dsr_info->dbi_outputs[0] = dbi_output; - else - dsr_info->dbi_outputs[1] = dbi_output; - - dsr_info->dbi_output_num++; - } -#endif - - PSB_DEBUG_ENTRY("successfully\n"); - - return &dbi_output->base; - -out_err1: - if(dbi_output) { - kfree(dbi_output); - } - - return NULL; -} diff --git a/drivers/staging/mrst/drv/mdfld_dsi_dbi.c b/drivers/staging/mrst/drv/mdfld_dsi_dbi.c new file mode 120000 index 0000000..2479356 --- /dev/null +++ b/drivers/staging/mrst/drv/mdfld_dsi_dbi.c @@ -0,0 +1 @@ +../../mrst.mcg/drv/mdfld_dsi_dbi.c \ No newline at end of file diff --git a/drivers/staging/mrst/drv/mdfld_dsi_dbi.h b/drivers/staging/mrst/drv/mdfld_dsi_dbi.h deleted file mode 100644 index 04d3fba..0000000 --- a/drivers/staging/mrst/drv/mdfld_dsi_dbi.h +++ /dev/null @@ -1,171 +0,0 @@ -/* - * Copyright © 2010 Intel Corporation - * - * Permission is hereby granted, free of charge, to any person obtaining a - * copy of this software and associated documentation files (the "Software"), - * to deal in the Software without restriction, including without limitation - * the rights to use, copy, modify, merge, publish, distribute, sublicense, - * and/or sell copies of the Software, and to permit persons to whom the - * Software is furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice (including the next - * paragraph) shall be included in all copies or substantial portions of the - * Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL - * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING - * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER - * DEALINGS IN THE SOFTWARE. - * - * Authors: - * jim liu - * Jackie Li - */ - -#ifndef __MDFLD_DSI_DBI_H__ -#define __MDFLD_DSI_DBI_H__ - -#include -#include -#include -#include -#include -#include - -#include "psb_drv.h" -#include "psb_intel_drv.h" -#include "psb_intel_reg.h" -#include "psb_powermgmt.h" - -#include "mdfld_dsi_output.h" -#include "mdfld_output.h" - -/* - * DBI encoder which inherits from mdfld_dsi_encoder - */ -struct mdfld_dsi_dbi_output { - struct mdfld_dsi_encoder base; - - struct drm_display_mode * panel_fixed_mode; - - u8 last_cmd; - - u8 lane_count; - - u8 channel_num; - - struct drm_device * dev; - - /*backlight operations*/ - - u32 dsr_idle_count; - bool dsr_fb_update_done; - - /*mode setting flags*/ - u32 mode_flags; - - /*panel status*/ - bool dbi_panel_on; - bool first_boot; - struct panel_funcs* p_funcs; -}; - -#define MDFLD_DSI_DBI_OUTPUT(dsi_encoder) container_of(dsi_encoder, struct mdfld_dsi_dbi_output, base) - -struct mdfld_dbi_dsr_info { - int dbi_output_num; - struct mdfld_dsi_dbi_output * dbi_outputs[2]; - - u32 dsr_idle_count; -}; - -#define DBI_CB_TIMEOUT_COUNT 0xffff - -/*offsets*/ -#define CMD_MEM_ADDR_OFFSET 0 - -#define CMD_DATA_SRC_SYSTEM_MEM 0 -#define CMD_DATA_SRC_PIPE 1 - -static inline int mdfld_dsi_dbi_fifo_ready(struct mdfld_dsi_dbi_output * dbi_output) -{ - struct drm_device * dev = dbi_output->dev; - u32 retry = DBI_CB_TIMEOUT_COUNT; - int pipe = dbi_output->channel_num == 1 ? 2 : 0; - int ret = 0; - - /*query the dbi fifo status*/ - retry = DBI_CB_TIMEOUT_COUNT; - while(retry--) { - if (REG_READ(MIPI_GEN_FIFO_STAT_REG(pipe)) & BIT(27)) - break; - } - - if(!retry) { - DRM_ERROR("Timeout waiting for DBI FIFO empty\n"); - ret = -EAGAIN; - } - - return ret; -} - -static inline int mdfld_dsi_dbi_cmd_sent(struct mdfld_dsi_dbi_output * dbi_output) -{ - struct drm_device * dev = dbi_output->dev; - u32 retry = DBI_CB_TIMEOUT_COUNT; - int pipe = dbi_output->channel_num == 1 ? 2 : 0; - int ret = 0; - - /*query the command execution status*/ - while(retry--) { - if (!(REG_READ(MIPI_CMD_ADD_REG(pipe)) & BIT(0))) - break; - } - - if(!retry) { - DRM_ERROR("Timeout waiting for DBI Command status\n"); - ret = -EAGAIN; - } - - return ret; -} - -static inline int mdfld_dsi_dbi_cb_ready(struct mdfld_dsi_dbi_output * dbi_output) -{ - int ret = 0; - - /*query the command execution status*/ - ret = mdfld_dsi_dbi_cmd_sent(dbi_output); - if(ret) { - DRM_ERROR("Perpheral is busy\n"); - ret = -EAGAIN; - } - /*query the dbi fifo status*/ - ret = mdfld_dsi_dbi_fifo_ready(dbi_output); - if(ret) { - DRM_ERROR("DBI FIFO is not empty\n"); - ret = -EAGAIN; - } - - return ret; -} - -/*export functions*/ -extern void mdfld_dsi_dbi_output_init(struct drm_device * dev, struct psb_intel_mode_device * mode_dev, int pipe); -extern void mdfld_dsi_dbi_exit_dsr (struct drm_device *dev, u32 update_src); -extern void mdfld_dsi_dbi_enter_dsr (struct mdfld_dsi_dbi_output * dbi_output, int pipe); -extern int mdfld_dbi_dsr_init(struct drm_device * dev); -extern void mdfld_dbi_dsr_exit(struct drm_device * dev); -extern struct mdfld_dsi_encoder * mdfld_dsi_dbi_init(struct drm_device * dev, - struct mdfld_dsi_connector * dsi_connector, - struct panel_funcs* p_funcs); -extern int mdfld_dsi_dbi_update_area(struct mdfld_dsi_dbi_output * dbi_output, u16 x1, u16 y1, u16 x2, u16 y2); -extern int mdfld_dsi_dbi_update_power(struct mdfld_dsi_dbi_output * dbi_output, int mode); -extern void mdfld_dsi_controller_dbi_init(struct mdfld_dsi_config * dsi_config, int pipe); - -extern struct mdfld_dsi_dbi_output *gdbi_output; - -#endif /*__MDFLD_DSI_DBI_H__*/ diff --git a/drivers/staging/mrst/drv/mdfld_dsi_dbi.h b/drivers/staging/mrst/drv/mdfld_dsi_dbi.h new file mode 120000 index 0000000..b4b09f7 --- /dev/null +++ b/drivers/staging/mrst/drv/mdfld_dsi_dbi.h @@ -0,0 +1 @@ +../../mrst.mcg/drv/mdfld_dsi_dbi.h \ No newline at end of file diff --git a/drivers/staging/mrst/drv/mdfld_dsi_dpi.c b/drivers/staging/mrst/drv/mdfld_dsi_dpi.c deleted file mode 100644 index e146e8b..0000000 --- a/drivers/staging/mrst/drv/mdfld_dsi_dpi.c +++ /dev/null @@ -1,1080 +0,0 @@ -/* - * Copyright © 2010 Intel Corporation - * - * Permission is hereby granted, free of charge, to any person obtaining a - * copy of this software and associated documentation files (the "Software"), - * to deal in the Software without restriction, including without limitation - * the rights to use, copy, modify, merge, publish, distribute, sublicense, - * and/or sell copies of the Software, and to permit persons to whom the - * Software is furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice (including the next - * paragraph) shall be included in all copies or substantial portions of the - * Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL - * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING - * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER - * DEALINGS IN THE SOFTWARE. - * - * Authors: - * jim liu - * Jackie Li - */ - -#include "mdfld_dsi_dpi.h" -#include "mdfld_output.h" -#include "mdfld_dsi_pkg_sender.h" -#include "psb_powermgmt.h" -#include "psb_drv.h" -#include "tc35876x-dsi-lvds.h" - -static void mdfld_dsi_dpi_shut_down(struct mdfld_dsi_dpi_output *output, int pipe); - -static void mdfld_wait_for_HS_DATA_FIFO(struct drm_device *dev, u32 pipe) -{ - u32 gen_fifo_stat_reg = MIPI_GEN_FIFO_STAT_REG(pipe); - int timeout = 0; - - udelay(500); - - /* This will time out after approximately 2+ seconds */ - while ((timeout < 20000) && (REG_READ(gen_fifo_stat_reg) & DSI_FIFO_GEN_HS_DATA_FULL)) { - udelay(100); - timeout++; - } - - if (timeout == 20000) - DRM_INFO("MIPI: HS Data FIFO was never cleared!\n"); -} - -static void mdfld_wait_for_HS_CTRL_FIFO(struct drm_device *dev, u32 pipe) -{ - u32 gen_fifo_stat_reg = MIPI_GEN_FIFO_STAT_REG(pipe); - int timeout = 0; - - udelay(500); - - /* This will time out after approximately 2+ seconds */ - while ((timeout < 20000) && (REG_READ(gen_fifo_stat_reg) & DSI_FIFO_GEN_HS_CTRL_FULL)) { - udelay(100); - timeout++; - } - if (timeout == 20000) - DRM_INFO("MIPI: HS CMD FIFO was never cleared!\n"); -} - -static void mdfld_wait_for_DPI_CTRL_FIFO(struct drm_device *dev, u32 pipe) -{ - u32 gen_fifo_stat_reg = MIPI_GEN_FIFO_STAT_REG(pipe); - int timeout = 0; - - udelay(500); - - /* This will time out after approximately 2+ seconds */ - while ((timeout < 20000) && ((REG_READ(gen_fifo_stat_reg) & DPI_FIFO_EMPTY) - != DPI_FIFO_EMPTY)) { - udelay(100); - timeout++; - } - - if (timeout == 20000) - DRM_INFO("MIPI: DPI FIFO was never cleared!\n"); -} - -static void mdfld_wait_for_SPL_PKG_SENT(struct drm_device *dev, u32 pipe) -{ - u32 intr_stat_reg = MIPI_INTR_STAT_REG(pipe); - int timeout = 0; - - udelay(500); - - /* This will time out after approximately 2+ seconds */ - while ((timeout < 20000) && (!(REG_READ(intr_stat_reg) & DSI_INTR_STATE_SPL_PKG_SENT))) { - udelay(100); - timeout++; - } - - if (timeout == 20000) - DRM_INFO("MIPI: SPL_PKT_SENT_INTERRUPT was not sent successfully!\n"); -} - -static void dsi_set_device_ready_state(struct drm_device *dev, int state, - int pipe) -{ - dev_dbg(&dev->pdev->dev, "%s: state = %d, pipe = %d\n", - __func__, state, pipe); - - REG_FLD_MOD(MIPI_DEVICE_READY_REG(pipe), !!state, 0, 0); -} - -static void dsi_set_pipe_plane_enable_state(struct drm_device *dev, int state, int pipe) -{ - struct drm_psb_private *dev_priv = dev->dev_private; - u32 pipeconf_reg = PSB_PIPECONF(PSB_PIPE_A); - u32 dspcntr_reg = PSB_DSPCNTR(PSB_PIPE_A); - - u32 pipeconf = dev_priv->pipeconf; - u32 dspcntr = dev_priv->dspcntr; - u32 mipi = MIPI_PORT_EN | PASS_FROM_SPHY_TO_AFE | SEL_FLOPPED_HSTX; - - dev_dbg(&dev->pdev->dev, "%s: state = %d, pipe = %d\n", - __func__, state, pipe); - - if (pipe) { - pipeconf_reg = PSB_PIPECONF(PSB_PIPE_C); - dspcntr_reg = PSB_DSPCNTR(PSB_PIPE_C); - } else { - mipi &= (~0x03); - } - - if (state) { - - /*Set up pipe */ - REG_WRITE(pipeconf_reg, BIT(31)); - - if (REG_BIT_WAIT(pipeconf_reg, 1, 30)) - dev_err(&dev->pdev->dev, "%s: Pipe enable timeout\n", - __func__); - - /*Set up display plane */ - REG_WRITE(dspcntr_reg, dspcntr); - } else { - u32 val; - u32 dspbase_reg = PSB_DSPBASE(pipe); - - /* Put DSI lanes to ULPS to disable pipe */ - REG_FLD_MOD(MIPI_DEVICE_READY_REG(pipe), 2, 2, 1); - REG_READ(MIPI_DEVICE_READY_REG(pipe)); /* posted write? */ - - /* LP Hold */ - REG_FLD_MOD(MIPI_PORT_CONTROL(pipe), 0, 16, 16); - REG_READ(MIPI_PORT_CONTROL(pipe)); /* posted write? */ - - /* Disable display plane */ - REG_FLD_MOD(dspcntr_reg, 0, 31, 31); - - /* Flush the plane changes ??? posted write? */ - REG_WRITE(dspbase_reg, REG_READ(dspbase_reg)); - REG_READ(dspbase_reg); - - /* Disable PIPE */ - REG_FLD_MOD(pipeconf_reg, 0, 31, 31); - - if (REG_BIT_WAIT(pipeconf_reg, 0, 30)) - dev_err(&dev->pdev->dev, "%s: Pipe disable timeout\n", - __func__); - - if (REG_BIT_WAIT(MIPI_GEN_FIFO_STAT_REG(pipe), 1, 28)) - dev_err(&dev->pdev->dev, "%s: FIFO not empty\n", - __func__); - } -} - -static void mdfld_dsi_configure_down(struct mdfld_dsi_encoder * dsi_encoder, int pipe) -{ - struct mdfld_dsi_dpi_output * dpi_output = MDFLD_DSI_DPI_OUTPUT(dsi_encoder); - struct mdfld_dsi_config * dsi_config = mdfld_dsi_encoder_get_config(dsi_encoder); - struct drm_device * dev = dsi_config->dev; - struct drm_psb_private * dev_priv = dev->dev_private; - - dev_dbg(&dev->pdev->dev, "Enter %s\n", __func__); - - if ((pipe == 0 && !dev_priv->dpi_panel_on) || - (pipe == 2 && !dev_priv->dpi_panel_on2)) { - dev_dbg(&dev->pdev->dev, "%s: DPI Panel is Already Off\n", - __func__); - return; - } - tc35876x_toshiba_bridge_panel_off(dev); - tc35876x_set_bridge_reset_state(dev, 1); - dsi_set_pipe_plane_enable_state(dev, 0, pipe); //Disable pipe and plane - - mdfld_dsi_dpi_shut_down(dpi_output, pipe); //Send shut down command - - dsi_set_device_ready_state(dev, 0, pipe); //Clear device ready state - - mdfld_pipe_disabled(dev, pipe); -} - -static void mdfld_dsi_configure_up(struct mdfld_dsi_encoder * dsi_encoder, int pipe) -{ - struct mdfld_dsi_dpi_output * dpi_output = MDFLD_DSI_DPI_OUTPUT(dsi_encoder); - struct mdfld_dsi_config * dsi_config = mdfld_dsi_encoder_get_config(dsi_encoder); - struct drm_device * dev = dsi_config->dev; - struct drm_psb_private * dev_priv = dev->dev_private; - - dev_dbg(&dev->pdev->dev, "Enter %s\n", __func__); - - if ((pipe == 0 && dev_priv->dpi_panel_on) || - (pipe == 2 && dev_priv->dpi_panel_on2)) { - dev_dbg(&dev->pdev->dev, "%s: DPI Panel is Already On\n", - __func__); - return; - } - - /* For resume path sequence */ - mdfld_dsi_dpi_shut_down(dpi_output, pipe); - dsi_set_device_ready_state(dev, 0, pipe); //Clear Device Ready Bit - - dsi_set_device_ready_state(dev, 1, pipe); //Set device ready state - tc35876x_set_bridge_reset_state(dev, 0); - tc35876x_configure_lvds_bridge(dev); - mdfld_dsi_dpi_turn_on(dpi_output, pipe); //Send turn on command - dsi_set_pipe_plane_enable_state(dev, 1, pipe); //Enable plane and pipe -} -/* End for TC35876X */ - -/* ************************************************************************* *\ - * FUNCTION: mdfld_dsi_tpo_ic_init - * - * DESCRIPTION: This function is called only by mrst_dsi_mode_set and - * restore_display_registers. since this function does not - * acquire the mutex, it is important that the calling function - * does! -\* ************************************************************************* */ -static void mdfld_dsi_tpo_ic_init(struct mdfld_dsi_config * dsi_config, u32 pipe) -{ - struct drm_device * dev = dsi_config->dev; - u32 dcsChannelNumber = dsi_config->channel_num; - u32 gen_data_reg = MIPI_HS_GEN_DATA_REG(pipe); - u32 gen_ctrl_reg = MIPI_HS_GEN_CTRL_REG(pipe); - u32 gen_ctrl_val = GEN_LONG_WRITE; - - DRM_INFO("Enter mrst init TPO MIPI display.\n"); - - gen_ctrl_val |= dcsChannelNumber << DCS_CHANNEL_NUMBER_POS; - - /* Flip page order */ - mdfld_wait_for_HS_DATA_FIFO(dev, pipe); - REG_WRITE(gen_data_reg, 0x00008036); - mdfld_wait_for_HS_CTRL_FIFO(dev, pipe); - REG_WRITE(gen_ctrl_reg, gen_ctrl_val | (0x02 << WORD_COUNTS_POS)); - - /* 0xF0 */ - mdfld_wait_for_HS_DATA_FIFO(dev, pipe); - REG_WRITE(gen_data_reg, 0x005a5af0); - mdfld_wait_for_HS_CTRL_FIFO(dev, pipe); - REG_WRITE(gen_ctrl_reg, gen_ctrl_val | (0x03 << WORD_COUNTS_POS)); - - /* Write protection key */ - mdfld_wait_for_HS_DATA_FIFO(dev, pipe); - REG_WRITE(gen_data_reg, 0x005a5af1); - mdfld_wait_for_HS_CTRL_FIFO(dev, pipe); - REG_WRITE(gen_ctrl_reg, gen_ctrl_val | (0x03 << WORD_COUNTS_POS)); - - /* 0xFC */ - mdfld_wait_for_HS_DATA_FIFO(dev, pipe); - REG_WRITE(gen_data_reg, 0x005a5afc); - mdfld_wait_for_HS_CTRL_FIFO(dev, pipe); - REG_WRITE(gen_ctrl_reg, gen_ctrl_val | (0x03 << WORD_COUNTS_POS)); - - /* 0xB7 */ - mdfld_wait_for_HS_DATA_FIFO(dev, pipe); - REG_WRITE(gen_data_reg, 0x770000b7); - mdfld_wait_for_HS_DATA_FIFO(dev, pipe); - REG_WRITE(gen_data_reg, 0x00000044); - mdfld_wait_for_HS_CTRL_FIFO(dev, pipe); - REG_WRITE(gen_ctrl_reg, gen_ctrl_val | (0x05 << WORD_COUNTS_POS)); - - /* 0xB6 */ - mdfld_wait_for_HS_DATA_FIFO(dev, pipe); - REG_WRITE(gen_data_reg, 0x000a0ab6); - mdfld_wait_for_HS_CTRL_FIFO(dev, pipe); - REG_WRITE(gen_ctrl_reg, gen_ctrl_val | (0x03 << WORD_COUNTS_POS)); - - /* 0xF2 */ - mdfld_wait_for_HS_DATA_FIFO(dev, pipe); - REG_WRITE(gen_data_reg, 0x081010f2); - mdfld_wait_for_HS_DATA_FIFO(dev, pipe); - REG_WRITE(gen_data_reg, 0x4a070708); - mdfld_wait_for_HS_DATA_FIFO(dev, pipe); - REG_WRITE(gen_data_reg, 0x000000c5); - mdfld_wait_for_HS_CTRL_FIFO(dev, pipe); - REG_WRITE(gen_ctrl_reg, gen_ctrl_val | (0x09 << WORD_COUNTS_POS)); - - /* 0xF8 */ - mdfld_wait_for_HS_DATA_FIFO(dev, pipe); - REG_WRITE(gen_data_reg, 0x024003f8); - mdfld_wait_for_HS_DATA_FIFO(dev, pipe); - REG_WRITE(gen_data_reg, 0x01030a04); - mdfld_wait_for_HS_DATA_FIFO(dev, pipe); - REG_WRITE(gen_data_reg, 0x0e020220); - mdfld_wait_for_HS_DATA_FIFO(dev, pipe); - REG_WRITE(gen_data_reg, 0x00000004); - mdfld_wait_for_HS_CTRL_FIFO(dev, pipe); - REG_WRITE(gen_ctrl_reg, gen_ctrl_val | (0x0d << WORD_COUNTS_POS)); - - /* 0xE2 */ - mdfld_wait_for_HS_DATA_FIFO(dev, pipe); - REG_WRITE(gen_data_reg, 0x398fc3e2); - mdfld_wait_for_HS_DATA_FIFO(dev, pipe); - REG_WRITE(gen_data_reg, 0x0000916f); - mdfld_wait_for_HS_CTRL_FIFO(dev, pipe); - REG_WRITE(gen_ctrl_reg, gen_ctrl_val | (0x06 << WORD_COUNTS_POS)); - - /* 0xB0 */ - mdfld_wait_for_HS_DATA_FIFO(dev, pipe); - REG_WRITE(gen_data_reg, 0x000000b0); - mdfld_wait_for_HS_CTRL_FIFO(dev, pipe); - REG_WRITE(gen_ctrl_reg, gen_ctrl_val | (0x02 << WORD_COUNTS_POS)); - - /* 0xF4 */ - mdfld_wait_for_HS_DATA_FIFO(dev, pipe); - REG_WRITE(gen_data_reg, 0x240242f4); - mdfld_wait_for_HS_DATA_FIFO(dev, pipe); - REG_WRITE(gen_data_reg, 0x78ee2002); - mdfld_wait_for_HS_DATA_FIFO(dev, pipe); - REG_WRITE(gen_data_reg, 0x2a071050); - mdfld_wait_for_HS_DATA_FIFO(dev, pipe); - REG_WRITE(gen_data_reg, 0x507fee10); - mdfld_wait_for_HS_DATA_FIFO(dev, pipe); - REG_WRITE(gen_data_reg, 0x10300710); - mdfld_wait_for_HS_CTRL_FIFO(dev, pipe); - REG_WRITE(gen_ctrl_reg, gen_ctrl_val | (0x14 << WORD_COUNTS_POS)); - - /* 0xBA */ - mdfld_wait_for_HS_DATA_FIFO(dev, pipe); - REG_WRITE(gen_data_reg, 0x19fe07ba); - mdfld_wait_for_HS_DATA_FIFO(dev, pipe); - REG_WRITE(gen_data_reg, 0x101c0a31); - mdfld_wait_for_HS_DATA_FIFO(dev, pipe); - REG_WRITE(gen_data_reg, 0x00000010); - mdfld_wait_for_HS_CTRL_FIFO(dev, pipe); - REG_WRITE(gen_ctrl_reg, gen_ctrl_val | (0x09 << WORD_COUNTS_POS)); - - /* 0xBB */ - mdfld_wait_for_HS_DATA_FIFO(dev, pipe); - REG_WRITE(gen_data_reg, 0x28ff07bb); - mdfld_wait_for_HS_DATA_FIFO(dev, pipe); - REG_WRITE(gen_data_reg, 0x24280a31); - mdfld_wait_for_HS_DATA_FIFO(dev, pipe); - REG_WRITE(gen_data_reg, 0x00000034); - mdfld_wait_for_HS_CTRL_FIFO(dev, pipe); - REG_WRITE(gen_ctrl_reg, gen_ctrl_val | (0x09 << WORD_COUNTS_POS)); - - /* 0xFB */ - mdfld_wait_for_HS_DATA_FIFO(dev, pipe); - REG_WRITE(gen_data_reg, 0x535d05fb); - mdfld_wait_for_HS_DATA_FIFO(dev, pipe); - REG_WRITE(gen_data_reg, 0x1b1a2130); - mdfld_wait_for_HS_DATA_FIFO(dev, pipe); - REG_WRITE(gen_data_reg, 0x221e180e); - mdfld_wait_for_HS_DATA_FIFO(dev, pipe); - REG_WRITE(gen_data_reg, 0x131d2120); - mdfld_wait_for_HS_DATA_FIFO(dev, pipe); - REG_WRITE(gen_data_reg, 0x535d0508); - mdfld_wait_for_HS_DATA_FIFO(dev, pipe); - REG_WRITE(gen_data_reg, 0x1c1a2131); - mdfld_wait_for_HS_DATA_FIFO(dev, pipe); - REG_WRITE(gen_data_reg, 0x231f160d); - mdfld_wait_for_HS_DATA_FIFO(dev, pipe); - REG_WRITE(gen_data_reg, 0x111b2220); - mdfld_wait_for_HS_DATA_FIFO(dev, pipe); - REG_WRITE(gen_data_reg, 0x535c2008); - mdfld_wait_for_HS_DATA_FIFO(dev, pipe); - REG_WRITE(gen_data_reg, 0x1f1d2433); - mdfld_wait_for_HS_DATA_FIFO(dev, pipe); - REG_WRITE(gen_data_reg, 0x2c251a10); - mdfld_wait_for_HS_DATA_FIFO(dev, pipe); - REG_WRITE(gen_data_reg, 0x2c34372d); - mdfld_wait_for_HS_DATA_FIFO(dev, pipe); - REG_WRITE(gen_data_reg, 0x00000023); - mdfld_wait_for_HS_CTRL_FIFO(dev, pipe); - REG_WRITE(gen_ctrl_reg, gen_ctrl_val | (0x31 << WORD_COUNTS_POS)); - - /* 0xFA */ - mdfld_wait_for_HS_DATA_FIFO(dev, pipe); - REG_WRITE(gen_data_reg, 0x525c0bfa); - mdfld_wait_for_HS_DATA_FIFO(dev, pipe); - REG_WRITE(gen_data_reg, 0x1c1c232f); - mdfld_wait_for_HS_DATA_FIFO(dev, pipe); - REG_WRITE(gen_data_reg, 0x2623190e); - mdfld_wait_for_HS_DATA_FIFO(dev, pipe); - REG_WRITE(gen_data_reg, 0x18212625); - mdfld_wait_for_HS_DATA_FIFO(dev, pipe); - REG_WRITE(gen_data_reg, 0x545d0d0e); - mdfld_wait_for_HS_DATA_FIFO(dev, pipe); - REG_WRITE(gen_data_reg, 0x1e1d2333); - mdfld_wait_for_HS_DATA_FIFO(dev, pipe); - REG_WRITE(gen_data_reg, 0x26231a10); - mdfld_wait_for_HS_DATA_FIFO(dev, pipe); - REG_WRITE(gen_data_reg, 0x1a222725); - mdfld_wait_for_HS_DATA_FIFO(dev, pipe); - REG_WRITE(gen_data_reg, 0x545d280f); - mdfld_wait_for_HS_DATA_FIFO(dev, pipe); - REG_WRITE(gen_data_reg, 0x21202635); - mdfld_wait_for_HS_DATA_FIFO(dev, pipe); - REG_WRITE(gen_data_reg, 0x31292013); - mdfld_wait_for_HS_DATA_FIFO(dev, pipe); - REG_WRITE(gen_data_reg, 0x31393d33); - mdfld_wait_for_HS_DATA_FIFO(dev, pipe); - REG_WRITE(gen_data_reg, 0x00000029); - mdfld_wait_for_HS_CTRL_FIFO(dev, pipe); - REG_WRITE(gen_ctrl_reg, gen_ctrl_val | (0x31 << WORD_COUNTS_POS)); - - /* Set DM */ - mdfld_wait_for_HS_DATA_FIFO(dev, pipe); - REG_WRITE(gen_data_reg, 0x000100f7); - mdfld_wait_for_HS_CTRL_FIFO(dev, pipe); - REG_WRITE(gen_ctrl_reg, gen_ctrl_val | (0x03 << WORD_COUNTS_POS)); -} - -static u16 mdfld_dsi_dpi_to_byte_clock_count(int pixel_clock_count, int num_lane, int bpp) -{ - return (u16)((pixel_clock_count * bpp) / (num_lane * 8)); -} - -/* - * Calculate the dpi time basing on a given drm mode @mode - * return 0 on success. - * FIXME: I was using proposed mode value for calculation, may need to - * use crtc mode values later - */ -int mdfld_dsi_dpi_timing_calculation(struct drm_display_mode * mode, - struct mdfld_dsi_dpi_timing * dpi_timing, - int num_lane, int bpp) -{ - int pclk_hsync, pclk_hfp, pclk_hbp, pclk_hactive; - int pclk_vsync, pclk_vfp, pclk_vbp, pclk_vactive; - - if(!mode || !dpi_timing) { - DRM_ERROR("Invalid parameter\n"); - return -EINVAL; - } - - PSB_DEBUG_ENTRY("pclk %d, hdisplay %d, hsync_start %d, hsync_end %d, htotal %d\n", - mode->clock, mode->hdisplay, mode->hsync_start, - mode->hsync_end, mode->htotal); - PSB_DEBUG_ENTRY("vdisplay %d, vsync_start %d, vsync_end %d, vtotal %d\n", - mode->vdisplay, mode->vsync_start, - mode->vsync_end, mode->vtotal); - - pclk_hactive = mode->hdisplay; - pclk_hfp = mode->hsync_start - mode->hdisplay; - pclk_hsync = mode->hsync_end - mode->hsync_start; - pclk_hbp = mode->htotal - mode->hsync_end; - - pclk_vactive = mode->vdisplay; - pclk_vfp = mode->vsync_start - mode->vdisplay; - pclk_vsync = mode->vsync_end - mode->vsync_start; - pclk_vbp = mode->vtotal - mode->vsync_end; - - /* - * byte clock counts were calculated by following formula - * bclock_count = pclk_count * bpp / num_lane / 8 - */ - dpi_timing->hsync_count = mdfld_dsi_dpi_to_byte_clock_count(pclk_hsync, num_lane, bpp); - dpi_timing->hbp_count = mdfld_dsi_dpi_to_byte_clock_count(pclk_hbp, num_lane, bpp); - dpi_timing->hfp_count = mdfld_dsi_dpi_to_byte_clock_count(pclk_hfp, num_lane, bpp); - dpi_timing->hactive_count = mdfld_dsi_dpi_to_byte_clock_count(pclk_hactive, num_lane, bpp); - dpi_timing->vsync_count = mdfld_dsi_dpi_to_byte_clock_count(pclk_vsync, num_lane, bpp); - dpi_timing->vbp_count = mdfld_dsi_dpi_to_byte_clock_count(pclk_vbp, num_lane, bpp); - dpi_timing->vfp_count = mdfld_dsi_dpi_to_byte_clock_count(pclk_vfp, num_lane, bpp); - - PSB_DEBUG_ENTRY("DPI timings: %d, %d, %d, %d, %d, %d, %d\n", - dpi_timing->hsync_count, dpi_timing->hbp_count, - dpi_timing->hfp_count, dpi_timing->hactive_count, - dpi_timing->vsync_count, dpi_timing->vbp_count, - dpi_timing->vfp_count); - - return 0; -} - -void mdfld_dsi_dpi_controller_init(struct mdfld_dsi_config * dsi_config, int pipe) -{ - struct drm_device * dev = dsi_config->dev; - int lane_count = dsi_config->lane_count; - struct mdfld_dsi_dpi_timing dpi_timing; - struct drm_display_mode * mode = dsi_config->mode; - u32 val = 0; - - PSB_DEBUG_ENTRY("Init DPI interface on pipe %d...\n", pipe); - - /*un-ready device*/ - REG_FLD_MOD(MIPI_DEVICE_READY_REG(pipe), 0, 0, 0); - - /*init dsi adapter before kicking off*/ - REG_WRITE(MIPI_CTRL_REG(pipe), 0x00000018); - - /*enable all interrupts*/ - REG_WRITE(MIPI_INTR_EN_REG(pipe), 0xffffffff); - - /*set up func_prg*/ - val |= lane_count; - val |= dsi_config->channel_num << DSI_DPI_VIRT_CHANNEL_OFFSET; - - switch(dsi_config->bpp) { - case 16: - val |= DSI_DPI_COLOR_FORMAT_RGB565; - break; - case 18: - val |= DSI_DPI_COLOR_FORMAT_RGB666; - break; - case 24: - val |= DSI_DPI_COLOR_FORMAT_RGB888; - break; - default: - DRM_ERROR("unsupported color format, bpp = %d\n", dsi_config->bpp); - } - REG_WRITE(MIPI_DSI_FUNC_PRG_REG(pipe), val); - - REG_WRITE(MIPI_HS_TX_TIMEOUT_REG(pipe), - (mode->vtotal * mode->htotal * dsi_config->bpp / (8 * lane_count)) & DSI_HS_TX_TIMEOUT_MASK); - REG_WRITE(MIPI_LP_RX_TIMEOUT_REG(pipe), 0xffff & DSI_LP_RX_TIMEOUT_MASK); - - /*max value: 20 clock cycles of txclkesc*/ - REG_WRITE(MIPI_TURN_AROUND_TIMEOUT_REG(pipe), 0x14 & DSI_TURN_AROUND_TIMEOUT_MASK); - - /*min 21 txclkesc, max: ffffh*/ - REG_WRITE(MIPI_DEVICE_RESET_TIMER_REG(pipe), 0xffff & DSI_RESET_TIMER_MASK); - - REG_WRITE(MIPI_DPI_RESOLUTION_REG(pipe), mode->vdisplay << 16 | mode->hdisplay); - - /*set DPI timing registers*/ - mdfld_dsi_dpi_timing_calculation(mode, &dpi_timing, dsi_config->lane_count, dsi_config->bpp); - - REG_WRITE(MIPI_HSYNC_COUNT_REG(pipe), dpi_timing.hsync_count & DSI_DPI_TIMING_MASK); - REG_WRITE(MIPI_HBP_COUNT_REG(pipe), dpi_timing.hbp_count & DSI_DPI_TIMING_MASK); - REG_WRITE(MIPI_HFP_COUNT_REG(pipe), dpi_timing.hfp_count & DSI_DPI_TIMING_MASK); - REG_WRITE(MIPI_HACTIVE_COUNT_REG(pipe), dpi_timing.hactive_count & DSI_DPI_TIMING_MASK); - REG_WRITE(MIPI_VSYNC_COUNT_REG(pipe), dpi_timing.vsync_count & DSI_DPI_TIMING_MASK); - REG_WRITE(MIPI_VBP_COUNT_REG(pipe), dpi_timing.vbp_count & DSI_DPI_TIMING_MASK); - REG_WRITE(MIPI_VFP_COUNT_REG(pipe), dpi_timing.vfp_count & DSI_DPI_TIMING_MASK); - - REG_WRITE(MIPI_HIGH_LOW_SWITCH_COUNT_REG(pipe), 0x46); - - /*min: 7d0 max: 4e20*/ - REG_WRITE(MIPI_INIT_COUNT_REG(pipe), 0x000007d0); - - /*set up video mode*/ - val = 0; - val = dsi_config->video_mode | DSI_DPI_COMPLETE_LAST_LINE; - REG_WRITE(MIPI_VIDEO_MODE_FORMAT_REG(pipe), val); - - REG_WRITE(MIPI_EOT_DISABLE_REG(pipe), 0x00000000); - - REG_WRITE(MIPI_LP_BYTECLK_REG(pipe), 0x00000004); - - /*TODO: figure out how to setup these registers*/ - if (get_panel_type(dev, pipe) == TC35876X) - REG_WRITE(MIPI_DPHY_PARAM_REG(pipe), 0x2A0c6008); - else - REG_WRITE(MIPI_DPHY_PARAM_REG(pipe), 0x150c3408); - - REG_WRITE(MIPI_CLK_LANE_SWITCH_TIME_CNT_REG(pipe), (0xa << 16) | 0x14); - - if (get_panel_type(dev, pipe) == TC35876X) - tc35876x_set_bridge_reset_state(dev, 0); /*Pull High Reset */ - - /*set device ready*/ - REG_FLD_MOD(MIPI_DEVICE_READY_REG(pipe), 1, 0, 0); -} - -void mdfld_dsi_dpi_turn_on(struct mdfld_dsi_dpi_output * output, int pipe) -{ - struct drm_device * dev = output->dev; - /* struct drm_psb_private * dev_priv = dev->dev_private; */ - - PSB_DEBUG_ENTRY("pipe %d panel state %d\n", pipe, output->panel_on); - -#if 0 /* what the hell, just do it */ - if(output->panel_on) - return; -#endif - - /* clear special packet sent bit */ - if (REG_READ(MIPI_INTR_STAT_REG(pipe)) & DSI_INTR_STATE_SPL_PKG_SENT) - REG_WRITE(MIPI_INTR_STAT_REG(pipe), DSI_INTR_STATE_SPL_PKG_SENT); - - /*send turn on package*/ - REG_WRITE(MIPI_DPI_CONTROL_REG(pipe), DSI_DPI_CTRL_HS_TURN_ON); - - /*wait for SPL_PKG_SENT interrupt*/ - mdfld_wait_for_SPL_PKG_SENT(dev, pipe); - - if (REG_READ(MIPI_INTR_STAT_REG(pipe)) & DSI_INTR_STATE_SPL_PKG_SENT) - REG_WRITE(MIPI_INTR_STAT_REG(pipe), DSI_INTR_STATE_SPL_PKG_SENT); - - output->panel_on = 1; - - /* FIXME the following is disabled to WA the X slow start issue for TMD panel */ - /* if(pipe == 2) */ - /* dev_priv->dpi_panel_on2 = true; */ - /* else if (pipe == 0) */ - /* dev_priv->dpi_panel_on = true; */ -} - -static void mdfld_dsi_dpi_shut_down(struct mdfld_dsi_dpi_output * output, int pipe) -{ - struct drm_device * dev = output->dev; - struct drm_psb_private *dev_priv = dev->dev_private; - /* struct drm_psb_private * dev_priv = dev->dev_private; */ - - PSB_DEBUG_ENTRY("pipe %d panel state %d\n", pipe, output->panel_on); - - /*if output is on, or mode setting didn't happen, ignore this*/ - if((!output->panel_on) || output->first_boot) { - output->first_boot = 0; - return; - } - - /* Wait for dpi fifo to empty */ - mdfld_wait_for_DPI_CTRL_FIFO(dev, pipe); - - /* Clear the special packet interrupt bit if set */ - if (REG_READ(MIPI_INTR_STAT_REG(pipe)) & DSI_INTR_STATE_SPL_PKG_SENT) - REG_WRITE(MIPI_INTR_STAT_REG(pipe), DSI_INTR_STATE_SPL_PKG_SENT); - - if (REG_READ(MIPI_DPI_CONTROL_REG(pipe)) == DSI_DPI_CTRL_HS_SHUTDOWN) { - PSB_DEBUG_ENTRY("try to send the same package again, abort!"); - goto shutdown_out; - } - - REG_WRITE(MIPI_DPI_CONTROL_REG(pipe), DSI_DPI_CTRL_HS_SHUTDOWN); - -shutdown_out: - output->panel_on = 0; - output->first_boot = 0; - - /* FIXME the following is disabled to WA the X slow start issue for TMD panel */ - /* if(pipe == 2) */ - /* dev_priv->dpi_panel_on2 = false; */ - /* else if (pipe == 0) */ - /* dev_priv->dpi_panel_on = false; */ -} - -static void mdfld_dsi_dpi_set_power(struct drm_encoder * encoder, bool on) -{ - struct mdfld_dsi_encoder * dsi_encoder = MDFLD_DSI_ENCODER(encoder); - struct mdfld_dsi_dpi_output * dpi_output = MDFLD_DSI_DPI_OUTPUT(dsi_encoder); - struct mdfld_dsi_config * dsi_config = mdfld_dsi_encoder_get_config(dsi_encoder); - int pipe = mdfld_dsi_encoder_get_pipe(dsi_encoder); - struct drm_device * dev = dsi_config->dev; - struct drm_psb_private * dev_priv = dev->dev_private; - u32 pipeconf_reg = PSB_PIPECONF(PSB_PIPE_A); - - PSB_DEBUG_ENTRY("set power %s on pipe %d\n", on ? "On" : "Off", pipe); - - if (pipe) - pipeconf_reg = PSB_PIPECONF(PSB_PIPE_C); - - /*start up display island if it was shutdown*/ - if (!ospm_power_using_hw_begin(OSPM_DISPLAY_ISLAND, true)) - return; - - if(on) { - if (get_panel_type(dev, pipe) == TMD_VID) { - mdfld_dsi_dpi_turn_on(dpi_output, pipe); - } else if (get_panel_type(dev, pipe) == TC35876X) { - mdfld_dsi_configure_up(dsi_encoder, pipe); - } else { - /*enable mipi port*/ - REG_WRITE(MIPI_PORT_CONTROL(pipe), - REG_READ(MIPI_PORT_CONTROL(pipe)) | BIT(31)); - REG_READ(MIPI_PORT_CONTROL(pipe)); - - mdfld_dsi_dpi_turn_on(dpi_output, pipe); - mdfld_dsi_tpo_ic_init(dsi_config, pipe); - } - - if(pipe == 2) { - dev_priv->dpi_panel_on2 = true; - } - else { - dev_priv->dpi_panel_on = true; - } - - } else { - if (get_panel_type(dev, pipe) == TMD_VID) { - mdfld_dsi_dpi_shut_down(dpi_output, pipe); - } else if (get_panel_type(dev, pipe) == TC35876X) { - mdfld_dsi_configure_down(dsi_encoder, pipe); - } else { - mdfld_dsi_dpi_shut_down(dpi_output, pipe); - - /*disable mipi port*/ - REG_WRITE(MIPI_PORT_CONTROL(pipe), - REG_READ(MIPI_PORT_CONTROL(pipe)) & ~BIT(31)); - REG_READ(MIPI_PORT_CONTROL(pipe)); - } - - if(pipe == 2) { - dev_priv->dpi_panel_on2 = false; - } - else { - dev_priv->dpi_panel_on = false; - } - - } - - ospm_power_using_hw_end(OSPM_DISPLAY_ISLAND); -} - -void mdfld_dsi_dpi_dpms(struct drm_encoder *encoder, int mode) -{ - PSB_DEBUG_ENTRY("%s \n", (mode == DRM_MODE_DPMS_ON ? "on":"off")); - - mdfld_dsi_dpi_set_power(encoder, mode == DRM_MODE_DPMS_ON); -} - -bool mdfld_dsi_dpi_mode_fixup(struct drm_encoder * encoder, - struct drm_display_mode * mode, - struct drm_display_mode * adjusted_mode) -{ - struct mdfld_dsi_encoder * dsi_encoder = MDFLD_DSI_ENCODER(encoder); - struct mdfld_dsi_config * dsi_config = mdfld_dsi_encoder_get_config(dsi_encoder); - struct drm_display_mode * fixed_mode = dsi_config->fixed_mode; - - PSB_DEBUG_ENTRY("\n"); - - if(fixed_mode) { - adjusted_mode->hdisplay = fixed_mode->hdisplay; - adjusted_mode->hsync_start = fixed_mode->hsync_start; - adjusted_mode->hsync_end = fixed_mode->hsync_end; - adjusted_mode->htotal = fixed_mode->htotal; - adjusted_mode->vdisplay = fixed_mode->vdisplay; - adjusted_mode->vsync_start = fixed_mode->vsync_start; - adjusted_mode->vsync_end = fixed_mode->vsync_end; - adjusted_mode->vtotal = fixed_mode->vtotal; - adjusted_mode->clock = fixed_mode->clock; - drm_mode_set_crtcinfo(adjusted_mode, CRTC_INTERLACE_HALVE_V); - } - - return true; -} - -void mdfld_dsi_dpi_prepare(struct drm_encoder * encoder) -{ - PSB_DEBUG_ENTRY("\n"); - - mdfld_dsi_dpi_set_power(encoder, false); -} - -void mdfld_dsi_dpi_commit(struct drm_encoder * encoder) -{ - PSB_DEBUG_ENTRY("\n"); - - mdfld_dsi_dpi_set_power(encoder, true); -} - -/* For TC35876X */ -/* This functionality was implemented in FW in iCDK */ -/* But removed in DV0 and later. So need to add here. */ -static void mipi_set_properties(struct mdfld_dsi_config *dsi_config, int pipe) -{ - struct drm_device *dev = dsi_config->dev; - - dev_dbg(&dev->pdev->dev, "Enter %s\n", __func__); - - REG_WRITE(MIPI_CTRL_REG(pipe), 0x00000018); - REG_WRITE(MIPI_INTR_EN_REG(pipe), 0xffffffff); - REG_WRITE(MIPI_HS_TX_TIMEOUT_REG(pipe), 0xffffff); - REG_WRITE(MIPI_LP_RX_TIMEOUT_REG(pipe), 0xffffff); - REG_WRITE(MIPI_TURN_AROUND_TIMEOUT_REG(pipe), 0x14); - REG_WRITE(MIPI_DEVICE_RESET_TIMER_REG(pipe), 0xff); - REG_WRITE(MIPI_HIGH_LOW_SWITCH_COUNT_REG(pipe), 0x25); - REG_WRITE(MIPI_INIT_COUNT_REG(pipe), 0xf0); - REG_WRITE(MIPI_EOT_DISABLE_REG(pipe), 0x00000000); - REG_WRITE(MIPI_LP_BYTECLK_REG(pipe), 0x00000004); - REG_WRITE(MIPI_DBI_BW_CTRL_REG(pipe), 0x00000820); - REG_WRITE(MIPI_CLK_LANE_SWITCH_TIME_CNT_REG(pipe), (0xa << 16) | 0x14); -} - -static void mdfld_mipi_set_video_timing(struct mdfld_dsi_config *dsi_config, - int pipe) -{ - struct drm_device *dev = dsi_config->dev; - struct mdfld_dsi_dpi_timing dpi_timing; - struct drm_display_mode *mode = dsi_config->mode; - - dev_dbg(&dev->pdev->dev, "Enter %s\n", __func__); - - mdfld_dsi_dpi_timing_calculation(mode, &dpi_timing, - dsi_config->lane_count, - dsi_config->bpp); - - REG_WRITE(MIPI_DPI_RESOLUTION_REG(pipe), - mode->vdisplay << 16 | mode->hdisplay); - REG_WRITE(MIPI_HSYNC_COUNT_REG(pipe), - dpi_timing.hsync_count & DSI_DPI_TIMING_MASK); - REG_WRITE(MIPI_HBP_COUNT_REG(pipe), - dpi_timing.hbp_count & DSI_DPI_TIMING_MASK); - REG_WRITE(MIPI_HFP_COUNT_REG(pipe), - dpi_timing.hfp_count & DSI_DPI_TIMING_MASK); - REG_WRITE(MIPI_HACTIVE_COUNT_REG(pipe), - dpi_timing.hactive_count & DSI_DPI_TIMING_MASK); - REG_WRITE(MIPI_VSYNC_COUNT_REG(pipe), - dpi_timing.vsync_count & DSI_DPI_TIMING_MASK); - REG_WRITE(MIPI_VBP_COUNT_REG(pipe), - dpi_timing.vbp_count & DSI_DPI_TIMING_MASK); - REG_WRITE(MIPI_VFP_COUNT_REG(pipe), - dpi_timing.vfp_count & DSI_DPI_TIMING_MASK); -} - -static void mdfld_mipi_config(struct mdfld_dsi_config *dsi_config, int pipe) -{ - struct drm_device *dev = dsi_config->dev; - int lane_count = dsi_config->lane_count; - - dev_dbg(&dev->pdev->dev, "Enter %s\n", __func__); - - if (pipe) { - REG_WRITE(MIPI_PORT_CONTROL(0), 0x00000002); - REG_WRITE(MIPI_PORT_CONTROL(2), 0x80000000); - } else { - REG_WRITE(MIPI_PORT_CONTROL(0), 0x80010000); - REG_WRITE(MIPI_PORT_CONTROL(2), 0x00); - } - - REG_WRITE(MIPI_DPHY_PARAM_REG(pipe), 0x150A600F); - REG_WRITE(MIPI_VIDEO_MODE_FORMAT_REG(pipe), 0x0000000F); - - /* lane_count = 3 */ - REG_WRITE(MIPI_DSI_FUNC_PRG_REG(pipe), 0x00000200 | lane_count); - - mdfld_mipi_set_video_timing(dsi_config, pipe); -} - -static void mdfld_set_pipe_timing(struct mdfld_dsi_config *dsi_config, int pipe) -{ - struct drm_device *dev = dsi_config->dev; - struct drm_display_mode *mode = dsi_config->mode; - - dev_dbg(&dev->pdev->dev, "Enter %s\n", __func__); - - REG_WRITE(PSB_HTOTAL(PSB_PIPE_A), - ((mode->htotal - 1) << 16) | (mode->hdisplay - 1)); - REG_WRITE(PSB_HBLANK(PSB_PIPE_A), - ((mode->htotal - 1) << 16) | (mode->hdisplay - 1)); - REG_WRITE(PSB_HSYNC(PSB_PIPE_A), - ((mode->hsync_end - 1) << 16) | (mode->hsync_start - 1)); - - REG_WRITE(PSB_VTOTAL(PSB_PIPE_A), \ - ((mode->vtotal - 1) << 16) | (mode->vdisplay - 1)); - REG_WRITE(PSB_VBLANK(PSB_PIPE_A), \ - ((mode->vtotal - 1) << 16) | (mode->vdisplay - 1)); - REG_WRITE(PSB_VSYNC(PSB_PIPE_A), - ((mode->vsync_end - 1) << 16) | (mode->vsync_start - 1)); - - REG_WRITE(PSB_PIPESRC(PSB_PIPE_A), - ((mode->hdisplay - 1) << 16) | (mode->vdisplay - 1)); -} -/* End for TC35876X */ - -void mdfld_dsi_dpi_mode_set(struct drm_encoder * encoder, - struct drm_display_mode * mode, - struct drm_display_mode * adjusted_mode) -{ - struct mdfld_dsi_encoder * dsi_encoder = MDFLD_DSI_ENCODER(encoder); - struct mdfld_dsi_dpi_output * dpi_output = MDFLD_DSI_DPI_OUTPUT(dsi_encoder); - struct mdfld_dsi_config * dsi_config = mdfld_dsi_encoder_get_config(dsi_encoder); - struct drm_device * dev = dsi_config->dev; - struct drm_psb_private * dev_priv = dev->dev_private; - int pipe = mdfld_dsi_encoder_get_pipe(dsi_encoder); - - u32 pipeconf_reg = PSB_PIPECONF(PSB_PIPE_A); - u32 dspcntr_reg = PSB_DSPCNTR(PSB_PIPE_A); - - u32 pipeconf = dev_priv->pipeconf; - u32 dspcntr = dev_priv->dspcntr; - u32 mipi = MIPI_PORT_EN | PASS_FROM_SPHY_TO_AFE | SEL_FLOPPED_HSTX; - - PSB_DEBUG_ENTRY("set mode %dx%d on pipe %d", mode->hdisplay, mode->vdisplay, pipe); - - if(pipe) { - pipeconf_reg = PSB_PIPECONF(PSB_PIPE_C); - dspcntr_reg = PSB_DSPCNTR(PSB_PIPE_C); - } else { - if (get_panel_type(dev, pipe) == TC35876X) - mipi &= (~0x03); /* Use all four lanes */ - else - mipi |= 2; - } - - /*start up display island if it was shutdown*/ - if (!ospm_power_using_hw_begin(OSPM_DISPLAY_ISLAND, true)) - return; - - if (get_panel_type(dev, pipe) == TC35876X) { - /* - * The following logic is required to reset the bridge and - * configure. This also starts the DSI clock at 200MHz. - */ - int timeout = 0; - - tc35876x_set_bridge_reset_state(dev, 0); /*Pull High Reset */ - tc35876x_toshiba_bridge_panel_on(dev); - udelay(100); - /* Now start the DSI clock */ - REG_WRITE(PSB_DSI_PLL_CTRL, 0x00); - REG_WRITE(PSB_DSI_PLL_DIV_M1, 0xC1); - REG_WRITE(PSB_DSI_PLL_CTRL, 0x00800000); - udelay(500); - REG_WRITE(PSB_DSI_PLL_CTRL, 0x80800000); - - if (REG_BIT_WAIT(pipeconf_reg, 1, 29)) - dev_err(&dev->pdev->dev, "%s: DSI PLL lock timeout\n", - __func__); - - REG_WRITE(MIPI_DPHY_PARAM_REG(pipe), 0x2A0c6008); - - mipi_set_properties(dsi_config, pipe); - mdfld_mipi_config(dsi_config, pipe); - mdfld_set_pipe_timing(dsi_config, pipe); - - REG_WRITE(VGACNTRL, 0x80000000); - REG_WRITE(DEVICE_READY_REG, 0x00000001); - - REG_WRITE(MIPI_PORT_CONTROL(pipe), BIT(31) | BIT(16)); - } else { - /*set up mipi port FIXME: do at init time */ - REG_WRITE(MIPI_PORT_CONTROL(pipe), mipi); - } - REG_READ(MIPI_PORT_CONTROL(pipe)); - - if (get_panel_type(dev, pipe) == TMD_VID) { - /* NOP */ - } else if (get_panel_type(dev, pipe) == TC35876X) { - /* set up DSI controller DPI interface */ - mdfld_dsi_dpi_controller_init(dsi_config, pipe); - - /* Configure MIPI Bridge and Panel */ - tc35876x_configure_lvds_bridge(dev); - dev_priv->dpi_panel_on = true; - } else { - /*turn on DPI interface*/ - mdfld_dsi_dpi_turn_on(dpi_output, pipe); - } - - /*set up pipe*/ - REG_WRITE(pipeconf_reg, pipeconf); - REG_READ(pipeconf_reg); - - /*set up display plane*/ - REG_WRITE(dspcntr_reg, dspcntr); - REG_READ(dspcntr_reg); - - msleep(20); /* FIXME: this should wait for vblank */ - - PSB_DEBUG_ENTRY("State %x, power %d\n", REG_READ(MIPI_INTR_STAT_REG(pipe)), - dpi_output->panel_on); - - if (get_panel_type(dev, pipe) == TMD_VID) { - /* NOP */ - } else if (get_panel_type(dev, pipe) == TC35876X) { - mdfld_dsi_dpi_turn_on(dpi_output, pipe); - } else { - /* init driver ic */ - mdfld_dsi_tpo_ic_init(dsi_config, pipe); - /*init backlight*/ - mdfld_dsi_brightness_init(dsi_config, pipe); - } - - ospm_power_using_hw_end(OSPM_DISPLAY_ISLAND); -} - -/* - * Init DSI DPI encoder. - * Allocate an mdfld_dsi_encoder and attach it to given @dsi_connector - * return pointer of newly allocated DPI encoder, NULL on error - */ -struct mdfld_dsi_encoder * mdfld_dsi_dpi_init(struct drm_device * dev, - struct mdfld_dsi_connector * dsi_connector, - struct panel_funcs* p_funcs) -{ - struct mdfld_dsi_dpi_output * dpi_output = NULL; - struct mdfld_dsi_config * dsi_config; - struct drm_connector * connector = NULL; - struct drm_encoder * encoder = NULL; - struct drm_display_mode * fixed_mode = NULL; - int pipe; - u32 data; - int ret; - - PSB_DEBUG_ENTRY("\n"); - - if (!dsi_connector || !p_funcs) { - DRM_ERROR("Invalid parameters\n"); - return NULL; - } - - pipe = dsi_connector->pipe; - - if (get_panel_type(dev, pipe) != TC35876X) { - dsi_config = mdfld_dsi_get_config(dsi_connector); - - /* panel hard-reset */ - if (p_funcs->reset) { - ret = p_funcs->reset(pipe); - if (ret) { - DRM_ERROR("Panel %d hard-reset failed\n", pipe); - return NULL; - } - } - - /* panel drvIC init */ - if (p_funcs->drv_ic_init) - p_funcs->drv_ic_init(dsi_config, pipe); - - /* panel power mode detect */ - ret = mdfld_dsi_get_power_mode(dsi_config, &data, false); - if (ret) { - DRM_ERROR("Panel %d get power mode failed\n", pipe); - dsi_connector->status = connector_status_disconnected; - } else { - DRM_INFO("pipe %d power mode 0x%x\n", pipe, data); - dsi_connector->status = connector_status_connected; - } - } - - dpi_output = kzalloc(sizeof(struct mdfld_dsi_dpi_output), GFP_KERNEL); - if(!dpi_output) { - DRM_ERROR("No memory\n"); - return NULL; - } - - if(dsi_connector->pipe) - dpi_output->panel_on = 0; - else - dpi_output->panel_on = 0; - - - dpi_output->dev = dev; - if (get_panel_type(dev, pipe) != TC35876X) - dpi_output->p_funcs = p_funcs; - dpi_output->first_boot = 1; - - /*get fixed mode*/ - dsi_config = mdfld_dsi_get_config(dsi_connector); - fixed_mode = dsi_config->fixed_mode; - - /*create drm encoder object*/ - connector = &dsi_connector->base.base; - encoder = &dpi_output->base.base; - drm_encoder_init(dev, - encoder, - p_funcs->encoder_funcs, - DRM_MODE_ENCODER_LVDS); - drm_encoder_helper_add(encoder, - p_funcs->encoder_helper_funcs); - - /*attach to given connector*/ - drm_mode_connector_attach_encoder(connector, encoder); - - /*set possible crtcs and clones*/ - if(dsi_connector->pipe) { - encoder->possible_crtcs = (1 << 2); - encoder->possible_clones = (1 << 1); - } else { - encoder->possible_crtcs = (1 << 0); - encoder->possible_clones = (1 << 0); - } - - PSB_DEBUG_ENTRY("successfully\n"); - - return &dpi_output->base; -} diff --git a/drivers/staging/mrst/drv/mdfld_dsi_dpi.c b/drivers/staging/mrst/drv/mdfld_dsi_dpi.c new file mode 120000 index 0000000..61fa1a1 --- /dev/null +++ b/drivers/staging/mrst/drv/mdfld_dsi_dpi.c @@ -0,0 +1 @@ +../../mrst.mcg/drv/mdfld_dsi_dpi.c \ No newline at end of file diff --git a/drivers/staging/mrst/drv/mdfld_dsi_dpi.h b/drivers/staging/mrst/drv/mdfld_dsi_dpi.h deleted file mode 100644 index 8426f22..0000000 --- a/drivers/staging/mrst/drv/mdfld_dsi_dpi.h +++ /dev/null @@ -1,77 +0,0 @@ -/* - * Copyright © 2010 Intel Corporation - * - * Permission is hereby granted, free of charge, to any person obtaining a - * copy of this software and associated documentation files (the "Software"), - * to deal in the Software without restriction, including without limitation - * the rights to use, copy, modify, merge, publish, distribute, sublicense, - * and/or sell copies of the Software, and to permit persons to whom the - * Software is furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice (including the next - * paragraph) shall be included in all copies or substantial portions of the - * Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL - * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING - * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER - * DEALINGS IN THE SOFTWARE. - * - * Authors: - * jim liu - * Jackie Li - */ - -#ifndef __MDFLD_DSI_DPI_H__ -#define __MDFLD_DSI_DPI_H__ - -#include "mdfld_dsi_output.h" -#include "mdfld_output.h" - -struct mdfld_dsi_dpi_timing { - u16 hsync_count; - u16 hbp_count; - u16 hfp_count; - u16 hactive_count; - u16 vsync_count; - u16 vbp_count; - u16 vfp_count; -}; - -struct mdfld_dsi_dpi_output { - struct mdfld_dsi_encoder base; - struct drm_device *dev; - - int panel_on; - int first_boot; - - struct panel_funcs *p_funcs; -}; - -#define MDFLD_DSI_DPI_OUTPUT(dsi_encoder) container_of(dsi_encoder, struct mdfld_dsi_dpi_output, base) - -/*export functions*/ -extern int mdfld_dsi_dpi_timing_calculation(struct drm_display_mode * mode, - struct mdfld_dsi_dpi_timing * dpi_timing, - int num_lane, int bpp); -extern struct mdfld_dsi_encoder * mdfld_dsi_dpi_init(struct drm_device * dev, - struct mdfld_dsi_connector * dsi_connector, - struct panel_funcs* p_funcs); - -/*MDFLD DPI helper functions*/ -extern void mdfld_dsi_dpi_dpms(struct drm_encoder *encoder, int mode); -extern bool mdfld_dsi_dpi_mode_fixup(struct drm_encoder * encoder, - struct drm_display_mode * mode, - struct drm_display_mode * adjusted_mode); -extern void mdfld_dsi_dpi_prepare(struct drm_encoder * encoder); -extern void mdfld_dsi_dpi_commit(struct drm_encoder * encoder); -extern void mdfld_dsi_dpi_mode_set(struct drm_encoder * encoder, - struct drm_display_mode * mode, - struct drm_display_mode * adjusted_mode); -extern void mdfld_dsi_dpi_turn_on(struct mdfld_dsi_dpi_output * output, - int pipe); -extern void mdfld_dsi_dpi_controller_init(struct mdfld_dsi_config * dsi_config, int pipe); -#endif /*__MDFLD_DSI_DPI_H__*/ diff --git a/drivers/staging/mrst/drv/mdfld_dsi_dpi.h b/drivers/staging/mrst/drv/mdfld_dsi_dpi.h new file mode 120000 index 0000000..da18dbf --- /dev/null +++ b/drivers/staging/mrst/drv/mdfld_dsi_dpi.h @@ -0,0 +1 @@ +../../mrst.mcg/drv/mdfld_dsi_dpi.h \ No newline at end of file diff --git a/drivers/staging/mrst/drv/mdfld_dsi_lvds_bridge.h b/drivers/staging/mrst/drv/mdfld_dsi_lvds_bridge.h new file mode 120000 index 0000000..e28b165 --- /dev/null +++ b/drivers/staging/mrst/drv/mdfld_dsi_lvds_bridge.h @@ -0,0 +1 @@ +../../mrst.mcg/drv/mdfld_dsi_lvds_bridge.h \ No newline at end of file diff --git a/drivers/staging/mrst/drv/mdfld_dsi_output.c b/drivers/staging/mrst/drv/mdfld_dsi_output.c deleted file mode 100644 index a5ab577..0000000 --- a/drivers/staging/mrst/drv/mdfld_dsi_output.c +++ /dev/null @@ -1,935 +0,0 @@ -/* - * Copyright © 2010 Intel Corporation - * - * Permission is hereby granted, free of charge, to any person obtaining a - * copy of this software and associated documentation files (the "Software"), - * to deal in the Software without restriction, including without limitation - * the rights to use, copy, modify, merge, publish, distribute, sublicense, - * and/or sell copies of the Software, and to permit persons to whom the - * Software is furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice (including the next - * paragraph) shall be included in all copies or substantial portions of the - * Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL - * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING - * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER - * DEALINGS IN THE SOFTWARE. - * - * Authors: - * jim liu - * Jackie Li - */ - -#include "mdfld_dsi_output.h" -#include "mdfld_dsi_dbi.h" -#include "mdfld_dsi_dpi.h" -#include "mdfld_output.h" -#include "mdfld_dsi_pkg_sender.h" -#include "tc35876x-dsi-lvds.h" -#include -#include - -/* get the LABC from command line. */ -static int LABC_control = 1; - -#ifdef MODULE -module_param (LABC_control, int, 0644); -#else - -static int __init parse_LABC_control(char *arg) -{ - /* LABC control can be passed in as a cmdline parameter */ - /* to enable this feature add LABC=1 to cmdline */ - /* to disable this feature add LABC=0 to cmdline */ - if (!arg) - return -EINVAL; - - if (!strcasecmp(arg, "0")) - LABC_control = 0; - else if (!strcasecmp (arg, "1")) - LABC_control = 1; - - return 0; -} -early_param ("LABC", parse_LABC_control); -#endif - -/** - * make these MCS command global - * we don't need 'movl' everytime we send them. - * FIXME: these datas were provided by OEM, we should get them from GCT. - **/ -/* FIXME: make the below data u8 instead of u32; note byte order! */ -static u32 mdfld_dbi_mcs_hysteresis[] = { - 0x42000f57, 0x8c006400, 0xff00bf00, 0xffffffff, - 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, - 0x38000aff, 0x82005000, 0xff00ab00, 0xffffffff, - 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, - 0x000000ff, -}; - -static u32 mdfld_dbi_mcs_display_profile[] = { - 0x50281450, 0x0000c882, 0x00000000, 0x00000000, - 0x00000000, -}; - -static u32 mdfld_dbi_mcs_kbbc_profile[] = { - 0x00ffcc60, 0x00000000, 0x00000000, 0x00000000, -}; - -static u32 mdfld_dbi_mcs_gamma_profile[] = { - 0x81111158, 0x88888888, 0x88888888, -}; - -/** - * Check and see if the generic control or data buffer is empty and ready. - */ -void mdfld_dsi_gen_fifo_ready (struct drm_device *dev, u32 gen_fifo_stat_reg, u32 fifo_stat) -{ - u32 GEN_BF_time_out_count = 0; - - /* Check MIPI Adatper command registers */ - for (GEN_BF_time_out_count = 0; GEN_BF_time_out_count < GEN_FB_TIME_OUT; GEN_BF_time_out_count++) - { - if ((REG_READ(gen_fifo_stat_reg) & fifo_stat) == fifo_stat) - break; - udelay (100); - } - - if (GEN_BF_time_out_count == GEN_FB_TIME_OUT) - DRM_ERROR("mdfld_dsi_gen_fifo_ready, Timeout. gen_fifo_stat_reg = 0x%x. \n", gen_fifo_stat_reg); -} - -/** - * Manage the DSI MIPI keyboard and display brightness. - * FIXME: this is exported to OSPM code. should work out an specific - * display interface to OSPM. - */ - -void mdfld_dsi_brightness_init (struct mdfld_dsi_config * dsi_config, int pipe) -{ - struct mdfld_dsi_pkg_sender * sender = mdfld_dsi_get_pkg_sender(dsi_config); - struct drm_device * dev = sender->dev; - struct drm_psb_private * dev_priv = dev->dev_private; - u32 gen_ctrl_val; - - if(!sender) { - DRM_ERROR("No sender found\n"); - } - /* Set default display backlight value to 85% (0xd8)*/ - mdfld_dsi_send_mcs_short(sender, write_display_brightness, 0xd8, 1, - true); - - /* Set minimum brightness setting of CABC function to 20% (0x33)*/ - mdfld_dsi_send_mcs_short(sender, write_cabc_min_bright, 0x33, 1, true); - - /* FIXME: make the below data u8 instead of u32; note byte order! */ - - /* write hysteresis values */ - mdfld_dsi_send_mcs_long(sender, (u8 *) mdfld_dbi_mcs_hysteresis, - sizeof(mdfld_dbi_mcs_hysteresis), true); - /* write display profile values */ - mdfld_dsi_send_mcs_long(sender, (u8 *) mdfld_dbi_mcs_display_profile, - sizeof(mdfld_dbi_mcs_display_profile), true); - /* write KBBC profile values */ - mdfld_dsi_send_mcs_long(sender, (u8 *) mdfld_dbi_mcs_kbbc_profile, - sizeof(mdfld_dbi_mcs_kbbc_profile), true); - /* write gamma setting */ - mdfld_dsi_send_mcs_long(sender, (u8 *) mdfld_dbi_mcs_gamma_profile, - sizeof(mdfld_dbi_mcs_gamma_profile), true); - - /* Enable backlight or/and LABC */ - gen_ctrl_val = BRIGHT_CNTL_BLOCK_ON | DISPLAY_DIMMING_ON| BACKLIGHT_ON; - if (LABC_control == 1) - gen_ctrl_val |= DISPLAY_DIMMING_ON| DISPLAY_BRIGHTNESS_AUTO | GAMMA_AUTO; - - if (LABC_control == 1) - gen_ctrl_val |= AMBIENT_LIGHT_SENSE_ON; - - dev_priv->mipi_ctrl_display = gen_ctrl_val; - - mdfld_dsi_send_mcs_short(sender, write_ctrl_display, (u8)gen_ctrl_val, - 1, true); - - mdfld_dsi_send_mcs_short(sender, write_ctrl_cabc, UI_IMAGE, 1, true); -} - -void mdfld_dsi_brightness_control (struct drm_device *dev, int pipe, int level) -{ - struct mdfld_dsi_pkg_sender * sender; - struct drm_psb_private * dev_priv; - struct mdfld_dsi_config * dsi_config; - u32 gen_ctrl_val = 0; - enum panel_type p_type = TMD_VID; - - if(!dev || (pipe != 0 && pipe != 2)) { - DRM_ERROR("Invalid parameter\n"); - return; - } - - p_type = get_panel_type(dev, 0); - - dev_priv = dev->dev_private; - - if(pipe) - dsi_config = dev_priv->dsi_configs[1]; - else - dsi_config = dev_priv->dsi_configs[0]; - - sender = mdfld_dsi_get_pkg_sender(dsi_config); - - if(!sender) { - DRM_ERROR("No sender found\n"); - return; - } - - gen_ctrl_val = ((level * 0xff) / MDFLD_DSI_BRIGHTNESS_MAX_LEVEL) & 0xff; - - PSB_DEBUG_ENTRY("pipe = %d, gen_ctrl_val = %d. \n", pipe, gen_ctrl_val); - - if(p_type == TMD_VID || p_type == TMD_CMD){ - /* Set display backlight value */ - mdfld_dsi_send_mcs_short(sender, tmd_write_display_brightness, - (u8)gen_ctrl_val, 1, true); - } else { - /* Set display backlight value */ - mdfld_dsi_send_mcs_short(sender, write_display_brightness, - (u8)gen_ctrl_val, 1, true); - - /* Enable backlight control */ - if (level == 0) - gen_ctrl_val = 0; - else - gen_ctrl_val = dev_priv->mipi_ctrl_display; - - mdfld_dsi_send_mcs_short(sender, write_ctrl_display, - (u8)gen_ctrl_val, 1, true); - } -} - -/* - * shut down DSI controller - */ -static void mdfld_dsi_controller_shutdown(struct mdfld_dsi_config * dsi_config, int pipe) -{ - struct drm_device * dev; - int retry = 100; - - PSB_DEBUG_ENTRY("shutting down DSI controller on pipe %d... dsi_config %p\n", pipe, dsi_config); - - if(!dsi_config) { - DRM_ERROR("Invalid parameter\n"); - return; - } - - dev = dsi_config->dev; - - if (!ospm_power_using_hw_begin(OSPM_DISPLAY_ISLAND, true)) { - DRM_ERROR("hw begin failed\n"); - return; - } - - if (!(REG_READ(MIPI_DEVICE_READY_REG(pipe)) & DSI_DEVICE_READY)) - goto shutdown_out; - - /*send shut down package, clean packet send bit first*/ - if (REG_READ(MIPI_INTR_STAT_REG(pipe)) & DSI_INTR_STATE_SPL_PKG_SENT) { - REG_WRITE(MIPI_INTR_STAT_REG(pipe), - (REG_READ(MIPI_INTR_STAT_REG(pipe)) | DSI_INTR_STATE_SPL_PKG_SENT)); - } - - /*send shut down package in HS*/ - REG_WRITE(MIPI_DPI_CONTROL_REG(pipe), DSI_DPI_CTRL_HS_SHUTDOWN); - - - /* - * make sure shut down is sent. - * FIXME: add max retry counter - */ - while (!(REG_READ(MIPI_INTR_STAT_REG(pipe)) & DSI_INTR_STATE_SPL_PKG_SENT)) { - retry--; - - if(!retry) { - PSB_DEBUG_ENTRY("timeout\n"); - break; - } - } - - /*sleep 1 ms to ensure shutdown finished*/ - msleep(100); - - /*un-ready device*/ - REG_WRITE(MIPI_DEVICE_READY_REG(pipe), - (REG_READ(MIPI_DEVICE_READY_REG(pipe)) & ~DSI_DEVICE_READY)); - -shutdown_out: - ospm_power_using_hw_end(OSPM_DISPLAY_ISLAND); -} - -static void mdfld_dsi_controller_startup(struct mdfld_dsi_config * dsi_config, int pipe) -{ - struct drm_device * dev; - int retry = 100; - - PSB_DEBUG_ENTRY("starting up DSI controller on pipe %d...\n", pipe); - - if(!dsi_config) { - DRM_ERROR("Invalid parameter\n"); - return; - } - - dev = dsi_config->dev; - - if (!ospm_power_using_hw_begin(OSPM_DISPLAY_ISLAND, true)) { - DRM_ERROR("hw begin failed\n"); - return; - } - - if ((REG_READ(MIPI_DEVICE_READY_REG(pipe)) & DSI_DEVICE_READY)) - goto startup_out; - - /*if config DPI, turn on DPI interface*/ - if(dsi_config->type == MDFLD_DSI_ENCODER_DPI) { - if (REG_READ(MIPI_INTR_STAT_REG(pipe)) & DSI_INTR_STATE_SPL_PKG_SENT) { - REG_WRITE(MIPI_INTR_STAT_REG(pipe), DSI_INTR_STATE_SPL_PKG_SENT); - } - - REG_WRITE(MIPI_DPI_CONTROL_REG(pipe), DSI_DPI_CTRL_HS_TURN_ON); - - /* - * make sure shut down is sent. - * FIXME: add max retry counter - */ - while (!(REG_READ(MIPI_INTR_STAT_REG(pipe)) & DSI_INTR_STATE_SPL_PKG_SENT)) { - retry--; - if(!retry) { - PSB_DEBUG_ENTRY("timeout\n"); - break; - } - } - - msleep(100); - } - - /*set device ready*/ - REG_WRITE(MIPI_DEVICE_READY_REG(pipe), - REG_READ(MIPI_DEVICE_READY_REG(pipe)) | DSI_DEVICE_READY); - -startup_out: - ospm_power_using_hw_end(OSPM_DISPLAY_ISLAND); -} - -static int mdfld_dsi_get_panel_status(struct mdfld_dsi_config *dsi_config, - u8 dcs, u32 *data, bool hs) -{ - struct mdfld_dsi_pkg_sender *sender - = mdfld_dsi_get_pkg_sender(dsi_config); - - if (!sender || !data) { - DRM_ERROR("Invalid parameter\n"); - return -EINVAL; - } - - return mdfld_dsi_read_mcs(sender, dcs, data, 1, hs); -} - -int mdfld_dsi_get_power_mode(struct mdfld_dsi_config *dsi_config, u32 *mode, - bool hs) -{ - if (!dsi_config || !mode) { - DRM_ERROR("Invalid parameter\n"); - return -EINVAL; - } - - return mdfld_dsi_get_panel_status(dsi_config, 0x0a, mode, hs); -} - -int mdfld_dsi_get_diagnostic_result(struct mdfld_dsi_config *dsi_config, - u32 *result, bool hs) -{ - if (!dsi_config || !result) { - DRM_ERROR("Invalid parameter\n"); - return -EINVAL; - } - - return mdfld_dsi_get_panel_status(dsi_config, 0x0f, result, hs); -} - -/* - * NOTE: this function was used by OSPM. - * TODO: will be removed later, should work out display interfaces for OSPM - */ -void mdfld_dsi_controller_init(struct mdfld_dsi_config * dsi_config, int pipe) -{ - if(!dsi_config || ((pipe != 0) && (pipe != 2))) { - DRM_ERROR("Invalid parameters\n"); - return; - } - - if (dsi_config->type == MDFLD_DSI_ENCODER_DPI) - mdfld_dsi_dpi_controller_init(dsi_config, pipe); - else if (dsi_config->type == MDFLD_DSI_ENCODER_DBI) - mdfld_dsi_controller_dbi_init(dsi_config, pipe); - else - DRM_ERROR("Bad DSI encoder type\n"); -} - -static void mdfld_dsi_connector_save(struct drm_connector * connector) -{ - PSB_DEBUG_ENTRY("\n"); -} - -static void mdfld_dsi_connector_restore(struct drm_connector * connector) -{ - PSB_DEBUG_ENTRY("\n"); -} - -/* FIXME: start using the force parameter */ -static enum drm_connector_status -mdfld_dsi_connector_detect(struct drm_connector *connector, bool force) -{ - struct psb_intel_output *psb_output - = to_psb_intel_output(connector); - struct mdfld_dsi_connector *dsi_connector - = MDFLD_DSI_CONNECTOR(psb_output); - - dsi_connector->status = connector_status_connected; - PSB_DEBUG_ENTRY("\n"); - - return dsi_connector->status; -} - -static int mdfld_dsi_connector_set_property(struct drm_connector * connector, - struct drm_property * property, - uint64_t value) -{ - struct drm_encoder * encoder = connector->encoder; - struct backlight_device * psb_bd; - - PSB_DEBUG_ENTRY("\n"); - - if (!strcmp(property->name, "scaling mode") && encoder) { - struct psb_intel_crtc * psb_crtc = to_psb_intel_crtc(encoder->crtc); - bool bTransitionFromToCentered; - uint64_t curValue; - - if (!psb_crtc) - goto set_prop_error; - - switch (value) { - case DRM_MODE_SCALE_FULLSCREEN: - break; - case DRM_MODE_SCALE_NO_SCALE: - break; - case DRM_MODE_SCALE_ASPECT: - break; - default: - goto set_prop_error; - } - - if (drm_connector_property_get_value(connector, property, &curValue)) - goto set_prop_error; - - if (curValue == value) - goto set_prop_done; - - if (drm_connector_property_set_value(connector, property, value)) - goto set_prop_error; - - bTransitionFromToCentered = (curValue == DRM_MODE_SCALE_NO_SCALE) || - (value == DRM_MODE_SCALE_NO_SCALE); - - if (psb_crtc->saved_mode.hdisplay != 0 && - psb_crtc->saved_mode.vdisplay != 0) { - if (bTransitionFromToCentered) { - if (!drm_crtc_helper_set_mode(encoder->crtc, &psb_crtc->saved_mode, - encoder->crtc->x, encoder->crtc->y, encoder->crtc->fb)) - goto set_prop_error; - } else { - struct drm_encoder_helper_funcs *pEncHFuncs = encoder->helper_private; - pEncHFuncs->mode_set(encoder, &psb_crtc->saved_mode, - &psb_crtc->saved_adjusted_mode); - } - } - } else if (!strcmp(property->name, "backlight") && encoder) { - PSB_DEBUG_ENTRY("backlight level = %d\n", (int)value); - if (drm_connector_property_set_value(connector, property, value)) - goto set_prop_error; - else { - PSB_DEBUG_ENTRY("set brightness to %d", (int)value); - psb_bd = psb_get_backlight_device(); - if(psb_bd) { - psb_bd->props.brightness = value; - psb_set_brightness(psb_bd); - } - } - } -set_prop_done: - return 0; -set_prop_error: - return -1; -} - -static void mdfld_dsi_connector_destroy(struct drm_connector * connector) -{ - struct psb_intel_output * psb_output = to_psb_intel_output(connector); - struct mdfld_dsi_connector * dsi_connector = MDFLD_DSI_CONNECTOR(psb_output); - struct mdfld_dsi_pkg_sender * sender; - - PSB_DEBUG_ENTRY("\n"); - - if(!dsi_connector) { - return; - } - - drm_sysfs_connector_remove(connector); - drm_connector_cleanup(connector); - - sender = dsi_connector->pkg_sender; - - mdfld_dsi_pkg_sender_destroy(sender); - - kfree(dsi_connector); -} - -static int mdfld_dsi_connector_get_modes(struct drm_connector * connector) -{ - struct psb_intel_output * psb_output = to_psb_intel_output(connector); - struct mdfld_dsi_connector * dsi_connector = MDFLD_DSI_CONNECTOR(psb_output); - struct mdfld_dsi_config * dsi_config = mdfld_dsi_get_config(dsi_connector); - struct drm_display_mode * fixed_mode = dsi_config->fixed_mode; - struct drm_display_mode * dup_mode = NULL; - struct drm_device * dev = connector->dev; - - PSB_DEBUG_ENTRY("\n"); - - connector->display_info.min_vfreq = 0; - connector->display_info.max_vfreq = 200; - connector->display_info.min_hfreq = 0; - connector->display_info.max_hfreq = 200; - - if(fixed_mode) { - PSB_DEBUG_ENTRY("fixed_mode %dx%d\n", fixed_mode->hdisplay, fixed_mode->vdisplay); - - dup_mode = drm_mode_duplicate(dev, fixed_mode); - drm_mode_probed_add(connector, dup_mode); - return 1; - } - - DRM_ERROR("Didn't get any modes!\n"); - - return 0; -} - -static int mdfld_dsi_connector_mode_valid(struct drm_connector * connector, struct drm_display_mode * mode) -{ - struct psb_intel_output * psb_output = to_psb_intel_output(connector); - struct mdfld_dsi_connector * dsi_connector = MDFLD_DSI_CONNECTOR(psb_output); - struct mdfld_dsi_config * dsi_config = mdfld_dsi_get_config(dsi_connector); - struct drm_display_mode * fixed_mode = dsi_config->fixed_mode; - - PSB_DEBUG_ENTRY("mode %p, fixed mode %p\n", mode, fixed_mode); - - if(mode->flags & DRM_MODE_FLAG_DBLSCAN) - return MODE_NO_DBLESCAN; - - if(mode->flags & DRM_MODE_FLAG_INTERLACE) - return MODE_NO_INTERLACE; - - /** - * FIXME: current DC has no fitting unit, reject any mode setting request - * will figure out a way to do up-scaling(pannel fitting) later. - **/ - if(fixed_mode) { - if(mode->hdisplay != fixed_mode->hdisplay) - return MODE_PANEL; - - if(mode->vdisplay != fixed_mode->vdisplay) - return MODE_PANEL; - } - - PSB_DEBUG_ENTRY("ok\n"); - - return MODE_OK; -} - -static void mdfld_dsi_connector_dpms(struct drm_connector *connector, int mode) -{ - if (mode == connector->dpms) - return; - - /*first, execute dpms*/ - - drm_helper_connector_dpms(connector, mode); -} - -static struct drm_encoder * mdfld_dsi_connector_best_encoder(struct drm_connector * connector) -{ - struct psb_intel_output * psb_output = to_psb_intel_output(connector); - struct mdfld_dsi_connector * dsi_connector = MDFLD_DSI_CONNECTOR(psb_output); - struct mdfld_dsi_config * dsi_config = mdfld_dsi_get_config(dsi_connector); - struct mdfld_dsi_encoder * encoder = NULL; - - PSB_DEBUG_ENTRY("config type %d\n", dsi_config->type); - - if(dsi_config->type == MDFLD_DSI_ENCODER_DBI) - encoder = dsi_config->encoders[MDFLD_DSI_ENCODER_DBI]; - else if (dsi_config->type == MDFLD_DSI_ENCODER_DPI) - encoder = dsi_config->encoders[MDFLD_DSI_ENCODER_DPI]; - - PSB_DEBUG_ENTRY("get encoder %p\n", encoder); - - if(!encoder) { - DRM_ERROR("Invalid encoder for type %d\n", dsi_config->type); - return NULL; - } - - dsi_config->encoder = encoder; - - return &encoder->base; -} - -/*DSI connector funcs*/ -static const struct drm_connector_funcs mdfld_dsi_connector_funcs = { - .dpms = /*drm_helper_connector_dpms*/mdfld_dsi_connector_dpms, - .save = mdfld_dsi_connector_save, - .restore = mdfld_dsi_connector_restore, - .detect = mdfld_dsi_connector_detect, - .fill_modes = drm_helper_probe_single_connector_modes, - .set_property = mdfld_dsi_connector_set_property, - .destroy = mdfld_dsi_connector_destroy, -}; - -/*DSI connector helper funcs*/ -static const struct drm_connector_helper_funcs mdfld_dsi_connector_helper_funcs = { - .get_modes = mdfld_dsi_connector_get_modes, - .mode_valid = mdfld_dsi_connector_mode_valid, - .best_encoder = mdfld_dsi_connector_best_encoder, -}; - -static int mdfld_dsi_get_default_config(struct drm_device * dev, - struct mdfld_dsi_config * config, int pipe) -{ - if(!dev || !config) { - DRM_ERROR("Invalid parameters"); - return -EINVAL; - } - - config->bpp = 24; - config->type = is_panel_vid_or_cmd(dev); - if (get_panel_type(dev, pipe) == TC35876X) - config->lane_count = 4; - else - config->lane_count = 2; - config->channel_num = 0; - /*NOTE: video mode is ignored when type is MDFLD_DSI_ENCODER_DBI*/ - if (get_panel_type(dev, pipe) == TMD_VID) { - config->video_mode = MDFLD_DSI_VIDEO_NON_BURST_MODE_SYNC_PULSE; - } else if (get_panel_type(dev, pipe) == TC35876X) { - config->video_mode = MDFLD_DSI_VIDEO_NON_BURST_MODE_SYNC_EVENTS; - } else { - config->video_mode = MDFLD_DSI_VIDEO_BURST_MODE; - } - - return 0; -} - -/* - * Returns the panel fixed mode from configuration. - */ -static struct drm_display_mode * -mdfld_dsi_get_configuration_mode(struct mdfld_dsi_config * dsi_config, int pipe) -{ - struct drm_device *dev = dsi_config->dev; - struct drm_display_mode *mode; - struct drm_psb_private *dev_priv = - (struct drm_psb_private *) dev->dev_private; - struct mrst_timing_info *ti = &dev_priv->gct_data.DTD; - bool use_gct = false; - - PSB_DEBUG_ENTRY("\n"); - - mode = kzalloc(sizeof(*mode), GFP_KERNEL); - if (!mode) - return NULL; - - if (use_gct) { - PSB_DEBUG_ENTRY("gct find MIPI panel. \n"); - - mode->hdisplay = (ti->hactive_hi << 8) | ti->hactive_lo; - mode->vdisplay = (ti->vactive_hi << 8) | ti->vactive_lo; - mode->hsync_start = mode->hdisplay + \ - ((ti->hsync_offset_hi << 8) | \ - ti->hsync_offset_lo); - mode->hsync_end = mode->hsync_start + \ - ((ti->hsync_pulse_width_hi << 8) | \ - ti->hsync_pulse_width_lo); - mode->htotal = mode->hdisplay + ((ti->hblank_hi << 8) | \ - ti->hblank_lo); - mode->vsync_start = \ - mode->vdisplay + ((ti->vsync_offset_hi << 8) | \ - ti->vsync_offset_lo); - mode->vsync_end = \ - mode->vsync_start + ((ti->vsync_pulse_width_hi << 8) | \ - ti->vsync_pulse_width_lo); - mode->vtotal = mode->vdisplay + \ - ((ti->vblank_hi << 8) | ti->vblank_lo); - mode->clock = ti->pixel_clock * 10; - - PSB_DEBUG_ENTRY("hdisplay is %d\n", mode->hdisplay); - PSB_DEBUG_ENTRY("vdisplay is %d\n", mode->vdisplay); - PSB_DEBUG_ENTRY("HSS is %d\n", mode->hsync_start); - PSB_DEBUG_ENTRY("HSE is %d\n", mode->hsync_end); - PSB_DEBUG_ENTRY("htotal is %d\n", mode->htotal); - PSB_DEBUG_ENTRY("VSS is %d\n", mode->vsync_start); - PSB_DEBUG_ENTRY("VSE is %d\n", mode->vsync_end); - PSB_DEBUG_ENTRY("vtotal is %d\n", mode->vtotal); - PSB_DEBUG_ENTRY("clock is %d\n", mode->clock); - } else { - if(dsi_config->type == MDFLD_DSI_ENCODER_DPI) { - if (get_panel_type(dev, pipe) == TMD_VID) { - mode->hdisplay = 480; - mode->vdisplay = 854; - mode->hsync_start = 487; - mode->hsync_end = 490; - mode->htotal = 499; - mode->vsync_start = 861; - mode->vsync_end = 865; - mode->vtotal = 873; - mode->clock = 33264; - } else { - mode->hdisplay = 864; - mode->vdisplay = 480; - mode->hsync_start = 873; - mode->hsync_end = 876; - mode->htotal = 887; - mode->vsync_start = 487; - mode->vsync_end = 490; - mode->vtotal = 499; - mode->clock = 33264; - } - } else if(dsi_config->type == MDFLD_DSI_ENCODER_DBI) { - mode->hdisplay = 864; - mode->vdisplay = 480; - mode->hsync_start = 872; - mode->hsync_end = 876; - mode->htotal = 884; - mode->vsync_start = 482; - mode->vsync_end = 494; - mode->vtotal = 486; - mode->clock = 25777; - - } - } - - drm_mode_set_name(mode); - drm_mode_set_crtcinfo(mode, 0); - - mode->type |= DRM_MODE_TYPE_PREFERRED; - - return mode; -} - -int mdfld_dsi_panel_reset(int pipe) -{ - unsigned gpio; - int ret = 0; - - switch (pipe) { - case 0: - gpio = 128; - break; - case 2: - gpio = 34; - break; - default: - DRM_ERROR("Invalid output\n"); - return -EINVAL; - } - - ret = gpio_request(gpio, "gfx"); - if (ret) { - DRM_ERROR("gpio_rqueset failed\n"); - return ret; - } - - ret = gpio_direction_output(gpio, 1); - if (ret) { - DRM_ERROR("gpio_direction_output failed\n"); - goto gpio_error; - } - - gpio_get_value(128); - -gpio_error: - if (gpio_is_valid(gpio)) - gpio_free(gpio); - - PSB_DEBUG_ENTRY("Panel reset done\n"); - - return ret; -} - -/* - * MIPI output init - * @dev drm device - * @pipe pipe number. 0 or 2 - * @config - * - * Do the initialization of a MIPI output, including create DRM mode objects - * initialization of DSI output on @pipe - */ -void mdfld_dsi_output_init(struct drm_device * dev, - int pipe, - struct mdfld_dsi_config * config, - struct panel_funcs* p_cmd_funcs, - struct panel_funcs* p_vid_funcs) -{ - struct mdfld_dsi_config * dsi_config; - struct mdfld_dsi_connector * dsi_connector; - struct psb_intel_output * psb_output; - struct drm_connector * connector; - struct mdfld_dsi_encoder * encoder; - struct drm_psb_private * dev_priv = dev->dev_private; - struct panel_info dsi_panel_info; - u32 width_mm, height_mm; - - PSB_DEBUG_ENTRY("init DSI output on pipe %d\n", pipe); - - if(!dev || ((pipe != 0) && (pipe != 2))) { - DRM_ERROR("Invalid parameter\n"); - return; - } - - /*create a new connetor*/ - dsi_connector = kzalloc(sizeof(struct mdfld_dsi_connector), GFP_KERNEL); - if(!dsi_connector) { - DRM_ERROR("No memory"); - return; - } - - dsi_connector->pipe = pipe; - - /*set DSI config*/ - if(config) { - dsi_config = config; - } else { - dsi_config = kzalloc(sizeof(struct mdfld_dsi_config), GFP_KERNEL); - if(!dsi_config) { - DRM_ERROR("cannot allocate memory for DSI config\n"); - goto dsi_init_err0; - } - - mdfld_dsi_get_default_config(dev, dsi_config, pipe); - } - - dsi_connector->private = dsi_config; - - dsi_config->changed = 1; - dsi_config->dev = dev; - - /*init fixed mode basing on DSI config type*/ - if(dsi_config->type == MDFLD_DSI_ENCODER_DBI) { - dsi_config->fixed_mode = p_cmd_funcs->get_config_mode(dev); - if(p_cmd_funcs->get_panel_info(dev, pipe, &dsi_panel_info)) - goto dsi_init_err0; - } else if(dsi_config->type == MDFLD_DSI_ENCODER_DPI) { - dsi_config->fixed_mode = p_vid_funcs->get_config_mode(dev); - if(p_vid_funcs->get_panel_info(dev, pipe, &dsi_panel_info)) - goto dsi_init_err0; - } - - width_mm = dsi_panel_info.width_mm; - height_mm = dsi_panel_info.height_mm; - - dsi_config->mode = dsi_config->fixed_mode; - dsi_config->connector = dsi_connector; - - if(!dsi_config->fixed_mode) { - DRM_ERROR("No pannel fixed mode was found\n"); - goto dsi_init_err0; - } - - if(pipe && dev_priv->dsi_configs[0]) { - dsi_config->dvr_ic_inited = 0; - dev_priv->dsi_configs[1] = dsi_config; - } else if(pipe == 0) { - dsi_config->dvr_ic_inited = 1; - dev_priv->dsi_configs[0] = dsi_config; - } else { - DRM_ERROR("Trying to init MIPI1 before MIPI0\n"); - goto dsi_init_err0; - } - - /*init drm connector object*/ - psb_output = &dsi_connector->base; - - psb_output->type = (pipe == 0) ? INTEL_OUTPUT_MIPI : INTEL_OUTPUT_MIPI2; - - connector = &psb_output->base; - drm_connector_init(dev, connector, &mdfld_dsi_connector_funcs, DRM_MODE_CONNECTOR_LVDS); - drm_connector_helper_add(connector, &mdfld_dsi_connector_helper_funcs); - - connector->display_info.subpixel_order = SubPixelHorizontalRGB; - connector->display_info.width_mm = width_mm; - connector->display_info.height_mm = height_mm; - connector->interlace_allowed = false; - connector->doublescan_allowed = false; - - /*attach properties*/ - drm_connector_attach_property(connector, dev->mode_config.scaling_mode_property, DRM_MODE_SCALE_FULLSCREEN); - drm_connector_attach_property(connector, dev_priv->backlight_property, MDFLD_DSI_BRIGHTNESS_MAX_LEVEL); - - /*init DSI package sender on this output*/ - if (mdfld_dsi_pkg_sender_init(dsi_connector, pipe)) { - DRM_ERROR("Package Sender initialization failed on pipe %d\n", pipe); - goto dsi_init_err0; - } - - /*create DBI & DPI encoders*/ - if(p_cmd_funcs) { - encoder = mdfld_dsi_dbi_init(dev, dsi_connector, p_cmd_funcs); - if(!encoder) { - DRM_ERROR("Create DBI encoder failed\n"); - goto dsi_init_err1; - } - encoder->private = dsi_config; - dsi_config->encoders[MDFLD_DSI_ENCODER_DBI] = encoder; - } - - if(p_vid_funcs) { - encoder = mdfld_dsi_dpi_init(dev, dsi_connector, p_vid_funcs); - if(!encoder) { - DRM_ERROR("Create DPI encoder failed\n"); - goto dsi_init_err1; - } - encoder->private = dsi_config; - dsi_config->encoders[MDFLD_DSI_ENCODER_DPI] = encoder; - } - - drm_sysfs_connector_add(connector); - - PSB_DEBUG_ENTRY("successfully\n"); - return; - - /*TODO: add code to destroy outputs on error*/ -dsi_init_err1: - /*destroy sender*/ - mdfld_dsi_pkg_sender_destroy(dsi_connector->pkg_sender); - - drm_connector_cleanup(connector); - - if(dsi_config->fixed_mode) - kfree(dsi_config->fixed_mode); - if(dsi_config) - kfree(dsi_config); -dsi_init_err0: - if(dsi_connector) { - kfree(dsi_connector); - } -} diff --git a/drivers/staging/mrst/drv/mdfld_dsi_output.c b/drivers/staging/mrst/drv/mdfld_dsi_output.c new file mode 120000 index 0000000..06feee2 --- /dev/null +++ b/drivers/staging/mrst/drv/mdfld_dsi_output.c @@ -0,0 +1 @@ +../../mrst.mcg/drv/mdfld_dsi_output.c \ No newline at end of file diff --git a/drivers/staging/mrst/drv/mdfld_dsi_output.h b/drivers/staging/mrst/drv/mdfld_dsi_output.h deleted file mode 100644 index 4d0e81c..0000000 --- a/drivers/staging/mrst/drv/mdfld_dsi_output.h +++ /dev/null @@ -1,354 +0,0 @@ -/* - * Copyright © 2010 Intel Corporation - * - * Permission is hereby granted, free of charge, to any person obtaining a - * copy of this software and associated documentation files (the "Software"), - * to deal in the Software without restriction, including without limitation - * the rights to use, copy, modify, merge, publish, distribute, sublicense, - * and/or sell copies of the Software, and to permit persons to whom the - * Software is furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice (including the next - * paragraph) shall be included in all copies or substantial portions of the - * Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL - * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING - * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER - * DEALINGS IN THE SOFTWARE. - * - * Authors: - * jim liu - * Jackie Li - */ - -#ifndef __MDFLD_DSI_OUTPUT_H__ -#define __MDFLD_DSI_OUTPUT_H__ - -#include -#include -#include -#include -#include -#include -#include - -#include "psb_drv.h" -#include "psb_intel_drv.h" -#include "psb_intel_reg.h" -#include "psb_powermgmt.h" -#include "mdfld_output.h" - -#include - -#define MDFLD_DSI_BRIGHTNESS_MAX_LEVEL 100 - -/* - * Actual MIPIA->MIPIC reg offset is 0x800, value 0x400 is valid for 0 and 2 - */ -#define CHECK_MIPI_PIPE(pipe) \ - (PSB_CHECK_PIPE(pipe, BIT(0) | BIT(2))) - -#define REG_OFFSET(pipe) (CHECK_MIPI_PIPE(pipe) * 0x400) - -/* mdfld DSI controller registers */ -#define MIPI_DEVICE_READY_REG(pipe) (0xb000 + REG_OFFSET(pipe)) -#define MIPI_INTR_STAT_REG(pipe) (0xb004 + REG_OFFSET(pipe)) -#define MIPI_INTR_EN_REG(pipe) (0xb008 + REG_OFFSET(pipe)) -#define MIPI_DSI_FUNC_PRG_REG(pipe) (0xb00c + REG_OFFSET(pipe)) -#define MIPI_HS_TX_TIMEOUT_REG(pipe) (0xb010 + REG_OFFSET(pipe)) -#define MIPI_LP_RX_TIMEOUT_REG(pipe) (0xb014 + REG_OFFSET(pipe)) -#define MIPI_TURN_AROUND_TIMEOUT_REG(pipe) (0xb018 + REG_OFFSET(pipe)) -#define MIPI_DEVICE_RESET_TIMER_REG(pipe) (0xb01c + REG_OFFSET(pipe)) -#define MIPI_DPI_RESOLUTION_REG(pipe) (0xb020 + REG_OFFSET(pipe)) -#define MIPI_DBI_FIFO_THROTTLE_REG(pipe) (0xb024 + REG_OFFSET(pipe)) -#define MIPI_HSYNC_COUNT_REG(pipe) (0xb028 + REG_OFFSET(pipe)) -#define MIPI_HBP_COUNT_REG(pipe) (0xb02c + REG_OFFSET(pipe)) -#define MIPI_HFP_COUNT_REG(pipe) (0xb030 + REG_OFFSET(pipe)) -#define MIPI_HACTIVE_COUNT_REG(pipe) (0xb034 + REG_OFFSET(pipe)) -#define MIPI_VSYNC_COUNT_REG(pipe) (0xb038 + REG_OFFSET(pipe)) -#define MIPI_VBP_COUNT_REG(pipe) (0xb03c + REG_OFFSET(pipe)) -#define MIPI_VFP_COUNT_REG(pipe) (0xb040 + REG_OFFSET(pipe)) -#define MIPI_HIGH_LOW_SWITCH_COUNT_REG(pipe) (0xb044 + REG_OFFSET(pipe)) -#define MIPI_DPI_CONTROL_REG(pipe) (0xb048 + REG_OFFSET(pipe)) -#define MIPI_DPI_DATA_REG(pipe) (0xb04c + REG_OFFSET(pipe)) -#define MIPI_INIT_COUNT_REG(pipe) (0xb050 + REG_OFFSET(pipe)) -#define MIPI_MAX_RETURN_PACK_SIZE_REG(pipe) (0xb054 + REG_OFFSET(pipe)) -#define MIPI_VIDEO_MODE_FORMAT_REG(pipe) (0xb058 + REG_OFFSET(pipe)) -#define MIPI_EOT_DISABLE_REG(pipe) (0xb05c + REG_OFFSET(pipe)) -#define MIPI_LP_BYTECLK_REG(pipe) (0xb060 + REG_OFFSET(pipe)) -#define MIPI_LP_GEN_DATA_REG(pipe) (0xb064 + REG_OFFSET(pipe)) -#define MIPI_HS_GEN_DATA_REG(pipe) (0xb068 + REG_OFFSET(pipe)) -#define MIPI_LP_GEN_CTRL_REG(pipe) (0xb06c + REG_OFFSET(pipe)) -#define MIPI_HS_GEN_CTRL_REG(pipe) (0xb070 + REG_OFFSET(pipe)) -#define MIPI_GEN_FIFO_STAT_REG(pipe) (0xb074 + REG_OFFSET(pipe)) -#define MIPI_HS_LS_DBI_ENABLE_REG(pipe) (0xb078 + REG_OFFSET(pipe)) -#define MIPI_DPHY_PARAM_REG(pipe) (0xb080 + REG_OFFSET(pipe)) -#define MIPI_DBI_BW_CTRL_REG(pipe) (0xb084 + REG_OFFSET(pipe)) -#define MIPI_CLK_LANE_SWITCH_TIME_CNT_REG(pipe) (0xb088 + REG_OFFSET(pipe)) - -#define MIPI_CTRL_REG(pipe) (0xb104 + REG_OFFSET(pipe)) -#define MIPI_DATA_ADD_REG(pipe) (0xb108 + REG_OFFSET(pipe)) -#define MIPI_DATA_LEN_REG(pipe) (0xb10c + REG_OFFSET(pipe)) -#define MIPI_CMD_ADD_REG(pipe) (0xb110 + REG_OFFSET(pipe)) -#define MIPI_CMD_LEN_REG(pipe) (0xb114 + REG_OFFSET(pipe)) - -/* non-uniform reg offset */ -#define MIPI_PORT_CONTROL(pipe) \ - (CHECK_MIPI_PIPE(pipe) ? MIPI_C : MIPI) - -#define DSI_DEVICE_READY (0x1) -#define DSI_POWER_STATE_ULPS_ENTER (0x2 << 1) -#define DSI_POWER_STATE_ULPS_EXIT (0x1 << 1) -#define DSI_POWER_STATE_ULPS_OFFSET (0x1) - - -#define DSI_ONE_DATA_LANE (0x1) -#define DSI_TWO_DATA_LANE (0x2) -#define DSI_THREE_DATA_LANE (0X3) -#define DSI_FOUR_DATA_LANE (0x4) -#define DSI_DPI_VIRT_CHANNEL_OFFSET (0x3) -#define DSI_DBI_VIRT_CHANNEL_OFFSET (0x5) -#define DSI_DPI_COLOR_FORMAT_RGB565 (0x01 << 7) -#define DSI_DPI_COLOR_FORMAT_RGB666 (0x02 << 7) -#define DSI_DPI_COLOR_FORMAT_RGB666_UNPACK (0x03 << 7) -#define DSI_DPI_COLOR_FORMAT_RGB888 (0x04 << 7) -#define DSI_DBI_COLOR_FORMAT_OPTION2 (0x05 << 13) - -#define DSI_INTR_STATE_RXSOTERROR BIT(0) - -#define DSI_INTR_STATE_SPL_PKG_SENT BIT(30) -#define DSI_INTR_STATE_TE BIT(31) - -#define DSI_HS_TX_TIMEOUT_MASK (0xffffff) - -#define DSI_LP_RX_TIMEOUT_MASK (0xffffff) - -#define DSI_TURN_AROUND_TIMEOUT_MASK (0x3f) - -#define DSI_RESET_TIMER_MASK (0xffff) - -#define DSI_DBI_FIFO_WM_HALF (0x0) -#define DSI_DBI_FIFO_WM_QUARTER (0x1) -#define DSI_DBI_FIFO_WM_LOW (0x2) - -#define DSI_DPI_TIMING_MASK (0xffff) - -#define DSI_INIT_TIMER_MASK (0xffff) - -#define DSI_DBI_RETURN_PACK_SIZE_MASK (0x3ff) - -#define DSI_LP_BYTECLK_MASK (0x0ffff) - -#define DSI_HS_CTRL_GEN_SHORT_W0 (0x03) -#define DSI_HS_CTRL_GEN_SHORT_W1 (0x13) -#define DSI_HS_CTRL_GEN_SHORT_W2 (0x23) -#define DSI_HS_CTRL_GEN_R0 (0x04) -#define DSI_HS_CTRL_GEN_R1 (0x14) -#define DSI_HS_CTRL_GEN_R2 (0x24) -#define DSI_HS_CTRL_GEN_LONG_W (0x29) -#define DSI_HS_CTRL_MCS_SHORT_W0 (0x05) -#define DSI_HS_CTRL_MCS_SHORT_W1 (0x15) -#define DSI_HS_CTRL_MCS_R0 (0x06) -#define DSI_HS_CTRL_MCS_LONG_W (0x39) -#define DSI_HS_CTRL_VC_OFFSET (0x06) -#define DSI_HS_CTRL_WC_OFFSET (0x08) - -#define DSI_FIFO_GEN_HS_DATA_FULL BIT(0) -#define DSI_FIFO_GEN_HS_DATA_HALF_EMPTY BIT(1) -#define DSI_FIFO_GEN_HS_DATA_EMPTY BIT(2) -#define DSI_FIFO_GEN_LP_DATA_FULL BIT(8) -#define DSI_FIFO_GEN_LP_DATA_HALF_EMPTY BIT(9) -#define DSI_FIFO_GEN_LP_DATA_EMPTY BIT(10) -#define DSI_FIFO_GEN_HS_CTRL_FULL BIT(16) -#define DSI_FIFO_GEN_HS_CTRL_HALF_EMPTY BIT(17) -#define DSI_FIFO_GEN_HS_CTRL_EMPTY BIT(18) -#define DSI_FIFO_GEN_LP_CTRL_FULL BIT(24) -#define DSI_FIFO_GEN_LP_CTRL_HALF_EMPTY BIT(25) -#define DSI_FIFO_GEN_LP_CTRL_EMPTY BIT(26) -#define DSI_FIFO_DBI_EMPTY BIT(27) -#define DSI_FIFO_DPI_EMPTY BIT(28) - -#define DSI_DBI_HS_LP_SWITCH_MASK (0x1) - -#define DSI_HS_LP_SWITCH_COUNTER_OFFSET (0x0) -#define DSI_LP_HS_SWITCH_COUNTER_OFFSET (0x16) - -#define DSI_DPI_CTRL_HS_SHUTDOWN (0x00000001) -#define DSI_DPI_CTRL_HS_TURN_ON (0x00000002) - -/*dsi power modes*/ -#define DSI_POWER_MODE_DISPLAY_ON BIT(2) -#define DSI_POWER_MODE_NORMAL_ON BIT(3) -#define DSI_POWER_MODE_SLEEP_OUT BIT(4) -#define DSI_POWER_MODE_PARTIAL_ON BIT(5) -#define DSI_POWER_MODE_IDLE_ON BIT(6) - -typedef enum { - MDFLD_DSI_ENCODER_DBI = 0, - MDFLD_DSI_ENCODER_DPI, -} mdfld_dsi_encoder_t; - -enum { - MDFLD_DSI_VIDEO_NON_BURST_MODE_SYNC_PULSE = 1, - MDFLD_DSI_VIDEO_NON_BURST_MODE_SYNC_EVENTS = 2, - MDFLD_DSI_VIDEO_BURST_MODE = 3, -}; - -#define DSI_DPI_COMPLETE_LAST_LINE BIT(2) -#define DSI_DPI_DISABLE_BTA BIT(3) - -struct mdfld_dsi_connector_state { - u32 mipi_ctrl_reg; -}; - -struct mdfld_dsi_encoder_state { - -}; - -struct mdfld_dsi_connector { - /* - * This is ugly, but I have to use connector in it! :-( - * FIXME: use drm_connector instead. - */ - struct psb_intel_output base; - - int pipe; - void * private; - void * pkg_sender; - - /*connection status*/ - enum drm_connector_status status; -}; - -struct mdfld_dsi_encoder { - struct drm_encoder base; - void * private; -}; - -/* - * DSI config, consists of one DSI connector, two DSI encoders. - * DRM will pick up on DSI encoder basing on differents configs. - */ -struct mdfld_dsi_config { - struct drm_device * dev; - struct drm_display_mode * fixed_mode; - struct drm_display_mode * mode; - - struct mdfld_dsi_connector * connector; - struct mdfld_dsi_encoder * encoders[DRM_CONNECTOR_MAX_ENCODER]; - struct mdfld_dsi_encoder * encoder; - - int changed; - - int bpp; - mdfld_dsi_encoder_t type; - int lane_count; - /*Virtual channel number for this encoder*/ - int channel_num; - /*video mode configure*/ - int video_mode; - - int dvr_ic_inited; -}; - -#define MDFLD_DSI_CONNECTOR(psb_output) \ - (container_of(psb_output, struct mdfld_dsi_connector, base)) - -#define MDFLD_DSI_ENCODER(encoder) \ - (container_of(encoder, struct mdfld_dsi_encoder, base)) - -static inline struct mdfld_dsi_config * - mdfld_dsi_get_config(struct mdfld_dsi_connector * connector) -{ - if(!connector) { - return NULL; - } - - return (struct mdfld_dsi_config *)connector->private; -} - -static inline void * mdfld_dsi_get_pkg_sender(struct mdfld_dsi_config * config) -{ - struct mdfld_dsi_connector * dsi_connector; - - if(!config) - return NULL; - - dsi_connector = config->connector; - - if(!dsi_connector) - return NULL; - - return dsi_connector->pkg_sender; -} - -static inline struct mdfld_dsi_config * - mdfld_dsi_encoder_get_config(struct mdfld_dsi_encoder * encoder) -{ - if(!encoder) - return NULL; - return (struct mdfld_dsi_config *)encoder->private; -} - -static inline struct mdfld_dsi_connector * - mdfld_dsi_encoder_get_connector(struct mdfld_dsi_encoder * encoder) -{ - struct mdfld_dsi_config * config; - - if(!encoder) - return NULL; - - config = mdfld_dsi_encoder_get_config(encoder); - if(!config) - return NULL; - - return config->connector; -} - -static inline void * mdfld_dsi_encoder_get_pkg_sender(struct mdfld_dsi_encoder * encoder) -{ - struct mdfld_dsi_config * dsi_config; - - dsi_config = mdfld_dsi_encoder_get_config(encoder); - if(!dsi_config) - return NULL; - - return mdfld_dsi_get_pkg_sender(dsi_config); -} - -static inline int mdfld_dsi_encoder_get_pipe(struct mdfld_dsi_encoder * encoder) -{ - struct mdfld_dsi_connector * connector; - - if(!encoder) - return -1; - - connector = mdfld_dsi_encoder_get_connector(encoder); - if(!connector) - return -1; - - return connector->pipe; -} - -/*Export functions*/ -extern void mdfld_dsi_gen_fifo_ready (struct drm_device *dev, u32 gen_fifo_stat_reg, u32 fifo_stat); -extern void mdfld_dsi_brightness_init (struct mdfld_dsi_config * dsi_config, int pipe); -extern void mdfld_dsi_brightness_control (struct drm_device *dev, int pipe, int level); -extern void mdfld_dsi_output_init(struct drm_device * dev, - int pipe, - struct mdfld_dsi_config * config, - struct panel_funcs * p_cmd_funcs, - struct panel_funcs * p_vid_funcs); -extern void mdfld_dsi_controller_init(struct mdfld_dsi_config * dsi_config, int pipe); - -extern int mdfld_dsi_get_power_mode(struct mdfld_dsi_config *dsi_config, - u32 *mode, bool hs); -extern int mdfld_dsi_get_diagnostic_result(struct mdfld_dsi_config *dsi_config, - u32 *result, bool hs); -extern int mdfld_dsi_panel_reset(int pipe); - -#endif /*__MDFLD_DSI_OUTPUT_H__*/ diff --git a/drivers/staging/mrst/drv/mdfld_dsi_output.h b/drivers/staging/mrst/drv/mdfld_dsi_output.h new file mode 120000 index 0000000..15e9bc1 --- /dev/null +++ b/drivers/staging/mrst/drv/mdfld_dsi_output.h @@ -0,0 +1 @@ +../../mrst.mcg/drv/mdfld_dsi_output.h \ No newline at end of file diff --git a/drivers/staging/mrst/drv/mdfld_dsi_pkg_sender.c b/drivers/staging/mrst/drv/mdfld_dsi_pkg_sender.c deleted file mode 100644 index e20ccf6..0000000 --- a/drivers/staging/mrst/drv/mdfld_dsi_pkg_sender.c +++ /dev/null @@ -1,884 +0,0 @@ -/* - * Copyright © 2010 Intel Corporation - * - * Permission is hereby granted, free of charge, to any person obtaining a - * copy of this software and associated documentation files (the "Software"), - * to deal in the Software without restriction, including without limitation - * the rights to use, copy, modify, merge, publish, distribute, sublicense, - * and/or sell copies of the Software, and to permit persons to whom the - * Software is furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice (including the next - * paragraph) shall be included in all copies or substantial portions of the - * Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL - * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING - * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER - * DEALINGS IN THE SOFTWARE. - * - * Authors: - * Jackie Li - */ - -#include - -#include "mdfld_dsi_output.h" -#include "mdfld_dsi_pkg_sender.h" -#include "mdfld_dsi_dbi.h" -#include "mdfld_dsi_dpi.h" - -#define MDFLD_DSI_DBI_FIFO_TIMEOUT 100 -#define MDFLD_DSI_READ_MAX_COUNT 5000 - -enum data_type { - DSI_DT_GENERIC_SHORT_WRITE_0 = 0x03, - DSI_DT_GENERIC_SHORT_WRITE_1 = 0x13, - DSI_DT_GENERIC_SHORT_WRITE_2 = 0x23, - DSI_DT_GENERIC_READ_0 = 0x04, - DSI_DT_GENERIC_READ_1 = 0x14, - DSI_DT_GENERIC_READ_2 = 0x24, - DSI_DT_GENERIC_LONG_WRITE = 0x29, - DSI_DT_DCS_SHORT_WRITE_0 = 0x05, - DSI_DT_DCS_SHORT_WRITE_1 = 0x15, - DSI_DT_DCS_READ = 0x06, - DSI_DT_DCS_LONG_WRITE = 0x39, -}; - -enum { - MDFLD_DSI_PANEL_MODE_SLEEP = 0x1, -}; - -enum { - MDFLD_DSI_PKG_SENDER_FREE = 0x0, - MDFLD_DSI_PKG_SENDER_BUSY = 0x1, -}; - -static const char * dsi_errors[] = { - "RX SOT Error", - "RX SOT Sync Error", - "RX EOT Sync Error", - "RX Escape Mode Entry Error", - "RX LP TX Sync Error", - "RX HS Receive Timeout Error", - "RX False Control Error", - "RX ECC Single Bit Error", - "RX ECC Multibit Error", - "RX Checksum Error", - "RX DSI Data Type Not Recognised", - "RX DSI VC ID Invalid", - "TX False Control Error", - "TX ECC Single Bit Error", - "TX ECC Multibit Error", - "TX Checksum Error", - "TX DSI Data Type Not Recognised", - "TX DSI VC ID invalid", - "High Contention", - "Low contention", - "DPI FIFO Under run", - "HS TX Timeout", - "LP RX Timeout", - "Turn Around ACK Timeout", - "ACK With No Error", - "RX Invalid TX Length", - "RX Prot Violation", - "HS Generic Write FIFO Full", - "LP Generic Write FIFO Full", - "Generic Read Data Avail" - "Special Packet Sent", - "Tearing Effect", -}; - -static inline int wait_for_gen_fifo_empty(struct mdfld_dsi_pkg_sender * sender, - u32 mask) -{ - struct drm_device * dev = sender->dev; - u32 gen_fifo_stat_reg = sender->mipi_gen_fifo_stat_reg; - int retry = 0xffff; - - while(retry--) { - if((mask & REG_READ(gen_fifo_stat_reg)) == mask) - return 0; - udelay(100); - } - - DRM_ERROR("fifo is NOT empty 0x%08x\n", REG_READ(gen_fifo_stat_reg)); - return -EIO; -} - -static int wait_for_all_fifos_empty(struct mdfld_dsi_pkg_sender * sender) -{ - return wait_for_gen_fifo_empty(sender, (BIT(2) | BIT(10) | BIT(18) | BIT(26) | BIT(27) | BIT(28))); -} - -static int wait_for_lp_fifos_empty(struct mdfld_dsi_pkg_sender * sender) -{ - return wait_for_gen_fifo_empty(sender, (BIT(10) | BIT(26))); -} - -static int wait_for_hs_fifos_empty(struct mdfld_dsi_pkg_sender * sender) -{ - return wait_for_gen_fifo_empty(sender, (BIT(2) | BIT(18))); -} - -static int wait_for_dbi_fifo_empty(struct mdfld_dsi_pkg_sender * sender) -{ - return wait_for_gen_fifo_empty(sender, (BIT(27))); -} - -static int handle_dsi_error(struct mdfld_dsi_pkg_sender * sender, u32 mask) -{ - u32 intr_stat_reg = sender->mipi_intr_stat_reg; - struct drm_device * dev = sender->dev; - - PSB_DEBUG_ENTRY("Handling error 0x%08x\n", mask); - - switch(mask) { - case BIT(0): - case BIT(1): - case BIT(2): - case BIT(3): - case BIT(4): - case BIT(5): - case BIT(6): - case BIT(7): - case BIT(8): - case BIT(9): - case BIT(10): - case BIT(11): - case BIT(12): - case BIT(13): - PSB_DEBUG_ENTRY("No Action required\n"); - break; - case BIT(14): - /*wait for all fifo empty*/ - /*wait_for_all_fifos_empty(sender)*/; - break; - case BIT(15): - PSB_DEBUG_ENTRY("No Action required\n"); - break; - case BIT(16): - break; - case BIT(17): - break; - case BIT(18): - case BIT(19): - PSB_DEBUG_ENTRY("High/Low contention detected\n"); - /*wait for contention recovery time*/ - /*mdelay(10);*/ - /*wait for all fifo empty*/ - if(0) wait_for_all_fifos_empty(sender); - break; - case BIT(20): - PSB_DEBUG_ENTRY("No Action required\n"); - break; - case BIT(21): - /*wait for all fifo empty*/ - /*wait_for_all_fifos_empty(sender);*/ - break; - case BIT(22): - break; - case BIT(23): - case BIT(24): - case BIT(25): - case BIT(26): - case BIT(27): - PSB_DEBUG_ENTRY("HS Gen fifo full\n"); - REG_WRITE(intr_stat_reg, mask); - wait_for_hs_fifos_empty(sender); - break; - case BIT(28): - PSB_DEBUG_ENTRY("LP Gen fifo full\n"); - REG_WRITE(intr_stat_reg, mask); - wait_for_lp_fifos_empty(sender); - break; - case BIT(29): - case BIT(30): - case BIT(31): - PSB_DEBUG_ENTRY("No Action required\n"); - break; - } - - if(mask & REG_READ(intr_stat_reg)) { - PSB_DEBUG_ENTRY("Cannot clean interrupt 0x%08x\n", mask); - } - - return 0; -} - -static int dsi_error_handler(struct mdfld_dsi_pkg_sender * sender) -{ - struct drm_device * dev = sender->dev; - u32 intr_stat_reg = sender->mipi_intr_stat_reg; - u32 mask; - u32 intr_stat; - int i; - int err = 0; - - intr_stat = REG_READ(intr_stat_reg); - - for(i=0; i<32; i++) { - mask = (0x00000001UL) << i; - if(intr_stat & mask) { - PSB_DEBUG_ENTRY("[DSI]: %s\n", dsi_errors[i]); - err = handle_dsi_error(sender, mask); - if(err) - DRM_ERROR("Cannot handle error\n"); - } - } - - return err; -} - -static inline int dbi_cmd_sent(struct mdfld_dsi_pkg_sender * sender) -{ - struct drm_device * dev = sender->dev; - u32 retry = 0xffff; - u32 dbi_cmd_addr_reg = sender->mipi_cmd_addr_reg; - int ret = 0; - - /*query the command execution status*/ - while(retry--) { - if(!(REG_READ(dbi_cmd_addr_reg) & BIT(0))) - break; - } - - if(!retry) { - DRM_ERROR("Timeout waiting for DBI Command status\n"); - ret = -EAGAIN; - } - - return ret; -} - -static int send_short_pkg(struct mdfld_dsi_pkg_sender *sender, u8 data_type, - u8 cmd, u8 param, bool hs) -{ - struct drm_device * dev = sender->dev; - u32 ctrl_reg; - u32 val; - u8 virtual_channel = 0; - - if (hs) { - ctrl_reg = sender->mipi_hs_gen_ctrl_reg; - - /* FIXME: wait_for_hs_fifos_empty(sender); */ - } else { - ctrl_reg = sender->mipi_lp_gen_ctrl_reg; - - /* FIXME: wait_for_lp_fifos_empty(sender); */ - } - - val = FLD_VAL(param, 23, 16) | FLD_VAL(cmd, 15, 8) | - FLD_VAL(virtual_channel, 7, 6) | FLD_VAL(data_type, 5, 0); - - REG_WRITE(ctrl_reg, val); - - return 0; -} - -static int send_long_pkg(struct mdfld_dsi_pkg_sender *sender, u8 data_type, - u8 *data, int len, bool hs) -{ - struct drm_device * dev = sender->dev; - u32 ctrl_reg; - u32 data_reg; - u32 val; - u8 *p; - u8 b1, b2, b3, b4; - u8 virtual_channel = 0; - int i; - - if (hs) { - ctrl_reg = sender->mipi_hs_gen_ctrl_reg; - data_reg = sender->mipi_hs_gen_data_reg; - - /* FIXME: wait_for_hs_fifos_empty(sender); */ - } else { - ctrl_reg = sender->mipi_lp_gen_ctrl_reg; - data_reg = sender->mipi_lp_gen_data_reg; - - /* FIXME: wait_for_lp_fifos_empty(sender); */ - } - - p = data; - for (i = 0; i < len / 4; i++) { - b1 = *p++; - b2 = *p++; - b3 = *p++; - b4 = *p++; - - REG_WRITE(data_reg, b4 << 24 | b3 << 16 | b2 << 8 | b1); - } - - i = len % 4; - if (i) { - b1 = 0; b2 = 0; b3 = 0; - - switch (i) { - case 3: - b1 = *p++; - b2 = *p++; - b3 = *p++; - break; - case 2: - b1 = *p++; - b2 = *p++; - break; - case 1: - b1 = *p++; - break; - } - - REG_WRITE(data_reg, b3 << 16 | b2 << 8 | b1); - } - - val = FLD_VAL(len, 23, 8) | FLD_VAL(virtual_channel, 7, 6) | - FLD_VAL(data_type, 5, 0); - - REG_WRITE(ctrl_reg, val); - - return 0; -} - -static int send_pkg_prepare(struct mdfld_dsi_pkg_sender *sender, u8 data_type, - u8 *data, u16 len) -{ - u8 cmd; - - PSB_DEBUG_ENTRY("Prepare to Send type 0x%x pkg\n", data_type); - - switch (data_type) { - case DSI_DT_DCS_SHORT_WRITE_0: - case DSI_DT_DCS_SHORT_WRITE_1: - case DSI_DT_DCS_LONG_WRITE: - cmd = *data; - break; - default: - return 0; - } - - /*this prevents other package sending while doing msleep*/ - sender->status = MDFLD_DSI_PKG_SENDER_BUSY; - - /*wait for 120 milliseconds in case exit_sleep_mode just be sent*/ - if (unlikely(cmd == DCS_ENTER_SLEEP_MODE)) { - /*TODO: replace it with msleep later*/ - mdelay(120); - } - - if (unlikely(cmd == DCS_EXIT_SLEEP_MODE)) { - /*TODO: replace it with msleep later*/ - mdelay(120); - } - - return 0; -} - -static int send_pkg_done(struct mdfld_dsi_pkg_sender *sender, u8 data_type, - u8 *data, u16 len) -{ - u8 cmd; - - PSB_DEBUG_ENTRY("Sent type 0x%x pkg\n", data_type); - - switch (data_type) { - case DSI_DT_DCS_SHORT_WRITE_0: - case DSI_DT_DCS_SHORT_WRITE_1: - case DSI_DT_DCS_LONG_WRITE: - cmd = *data; - break; - default: - return 0; - } - - /*update panel status*/ - if (unlikely(cmd == DCS_ENTER_SLEEP_MODE)) { - sender->panel_mode |= MDFLD_DSI_PANEL_MODE_SLEEP; - /*TODO: replace it with msleep later*/ - mdelay(120); - } else if (unlikely(cmd == DCS_EXIT_SLEEP_MODE)) { - sender->panel_mode &= ~MDFLD_DSI_PANEL_MODE_SLEEP; - /*TODO: replace it with msleep later*/ - mdelay(120); - } else if (unlikely(cmd == DCS_SOFT_RESET)) { - /*TODO: replace it with msleep later*/ - mdelay(5); - } - - sender->status = MDFLD_DSI_PKG_SENDER_FREE; - - return 0; - -} - -static int send_pkg(struct mdfld_dsi_pkg_sender *sender, u8 data_type, - u8 *data, u16 len, bool hs) -{ - int ret; - - /*handle DSI error*/ - ret = dsi_error_handler(sender); - if (ret) { - DRM_ERROR("Error handling failed\n"); - return -EAGAIN; - } - - /* send pkg */ - PSB_DEBUG_ENTRY("Sending type 0x%x pkg\n", data_type); - - if (sender->status == MDFLD_DSI_PKG_SENDER_BUSY) { - DRM_ERROR("sender is busy\n"); - return -EAGAIN; - } - - ret = send_pkg_prepare(sender, data_type, data, len); - if (ret) { - DRM_ERROR("send_pkg_prepare error\n"); - return ret; - } - - switch (data_type) { - case DSI_DT_GENERIC_SHORT_WRITE_0: - case DSI_DT_GENERIC_SHORT_WRITE_1: - case DSI_DT_GENERIC_SHORT_WRITE_2: - case DSI_DT_GENERIC_READ_0: - case DSI_DT_GENERIC_READ_1: - case DSI_DT_GENERIC_READ_2: - case DSI_DT_DCS_SHORT_WRITE_0: - case DSI_DT_DCS_SHORT_WRITE_1: - case DSI_DT_DCS_READ: - ret = send_short_pkg(sender, data_type, data[0], data[1], hs); - break; - case DSI_DT_GENERIC_LONG_WRITE: - case DSI_DT_DCS_LONG_WRITE: - ret = send_long_pkg(sender, data_type, data, len, hs); - break; - } - - send_pkg_done(sender, data_type, data, len); - - /*FIXME: should I query complete and fifo empty here?*/ - - return ret; -} - -static int mdfld_dbi_cb_init(struct mdfld_dsi_pkg_sender * sender, struct psb_gtt * pg, int pipe) { - uint32_t phy; - void __iomem *virt_addr = NULL; - - switch(pipe) { - case 0: - phy = pg->gtt_phys_start - 0x1000; - break; - case 2: - phy = pg->gtt_phys_start - 0x800; - break; - default: - DRM_ERROR("Unsupported channel\n"); - return -EINVAL; - } - - /*mapping*/ - virt_addr = ioremap_nocache(phy, 0x800); - if(!virt_addr) { - DRM_ERROR("Map DBI command buffer error\n"); - return -ENOMEM; - } - - sender->dbi_cb_phy = phy; - sender->dbi_cb_addr = virt_addr; - - PSB_DEBUG_ENTRY("DBI command buffer initailized. phy %x, addr %p\n", phy, virt_addr); - - return 0; -} - -static void mdfld_dbi_cb_destroy(struct mdfld_dsi_pkg_sender * sender) { - PSB_DEBUG_ENTRY("\n"); - - if(sender && sender->dbi_cb_addr) - iounmap(sender->dbi_cb_addr); -} - -int mdfld_dsi_send_mcs_long(struct mdfld_dsi_pkg_sender *sender, u8 *data, - u32 len, bool hs) -{ - unsigned long flags; - - if (!sender || !data || !len) { - DRM_ERROR("Invalid parameters\n"); - return -EINVAL; - } - - spin_lock_irqsave(&sender->lock, flags); - send_pkg(sender, DSI_DT_DCS_LONG_WRITE, data, len, hs); - spin_unlock_irqrestore(&sender->lock, flags); - - return 0; -} - -int mdfld_dsi_send_mcs_short(struct mdfld_dsi_pkg_sender *sender, u8 cmd, - u8 param, u8 param_num, bool hs) -{ - u8 data[2]; - unsigned long flags; - u8 data_type; - - if (!sender) { - DRM_ERROR("Invalid parameter\n"); - return -EINVAL; - } - - data[0] = cmd; - - if (param_num) { - data_type = DSI_DT_DCS_SHORT_WRITE_1; - data[1] = param; - } else { - data_type = DSI_DT_DCS_SHORT_WRITE_0; - data[1] = 0; - } - - spin_lock_irqsave(&sender->lock, flags); - send_pkg(sender, data_type, data, sizeof(data), hs); - spin_unlock_irqrestore(&sender->lock, flags); - - return 0; -} - -int mdfld_dsi_send_gen_short(struct mdfld_dsi_pkg_sender *sender, u8 param0, - u8 param1, u8 param_num, bool hs) -{ - u8 data[2]; - unsigned long flags; - u8 data_type; - - if (!sender || param_num < 0 || param_num > 2) { - DRM_ERROR("Invalid parameter\n"); - return -EINVAL; - } - - switch (param_num) { - case 0: - data_type = DSI_DT_GENERIC_SHORT_WRITE_0; - data[0] = 0; - data[1] = 0; - break; - case 1: - data_type = DSI_DT_GENERIC_SHORT_WRITE_1; - data[0] = param0; - data[1] = 0; - break; - case 2: - data_type = DSI_DT_GENERIC_SHORT_WRITE_2; - data[0] = param0; - data[1] = param1; - break; - } - - spin_lock_irqsave(&sender->lock, flags); - send_pkg(sender, data_type, data, sizeof(data), hs); - spin_unlock_irqrestore(&sender->lock, flags); - - return 0; -} - -int mdfld_dsi_send_gen_long(struct mdfld_dsi_pkg_sender *sender, u8 *data, - u32 len, bool hs) -{ - unsigned long flags; - - if (!sender || !data || !len) { - DRM_ERROR("Invalid parameters\n"); - return -EINVAL; - } - - spin_lock_irqsave(&sender->lock, flags); - send_pkg(sender, DSI_DT_GENERIC_LONG_WRITE, data, len, hs); - spin_unlock_irqrestore(&sender->lock, flags); - - return 0; -} - -static int __read_panel_data(struct mdfld_dsi_pkg_sender *sender, u8 data_type, - u8 *data, u16 len, u32 *data_out, u16 len_out, bool hs) -{ - unsigned long flags; - struct drm_device *dev = sender->dev; - int i; - u32 gen_data_reg; - int retry = MDFLD_DSI_READ_MAX_COUNT; - - if (!sender || !data_out || !len_out) { - DRM_ERROR("Invalid parameters\n"); - return -EINVAL; - } - - /** - * do reading. - * 0) send out generic read request - * 1) polling read data avail interrupt - * 2) read data - */ - spin_lock_irqsave(&sender->lock, flags); - - REG_WRITE(sender->mipi_intr_stat_reg, BIT(29)); - - if ((REG_READ(sender->mipi_intr_stat_reg) & BIT(29))) - DRM_ERROR("Can NOT clean read data valid interrupt\n"); - - /*send out read request*/ - send_pkg(sender, data_type, data, len, hs); - - /*polling read data avail interrupt*/ - while (retry && !(REG_READ(sender->mipi_intr_stat_reg) & BIT(29))) { - udelay(100); - retry--; - } - - if (!retry) { - spin_unlock_irqrestore(&sender->lock, flags); - return -ETIMEDOUT; - } - - REG_WRITE(sender->mipi_intr_stat_reg, BIT(29)); - - /*read data*/ - if (hs) - gen_data_reg = sender->mipi_hs_gen_data_reg; - else - gen_data_reg = sender->mipi_lp_gen_data_reg; - - for (i = 0; i < len_out; i++) - *(data_out + i) = REG_READ(gen_data_reg); - - spin_unlock_irqrestore(&sender->lock, flags); - - return 0; -} - -static int mdfld_dsi_read_gen(struct mdfld_dsi_pkg_sender *sender, u8 param0, - u8 param1, u8 param_num, u32 *data, u16 len, bool hs) -{ - u8 data_type; - u8 cmd[2]; - - switch (param_num) { - case 0: - data_type = DSI_DT_GENERIC_READ_0; - cmd[0] = 0; - cmd[1] = 0; - break; - case 1: - data_type = DSI_DT_GENERIC_READ_1; - cmd[0] = param0; - cmd[1] = 0; - break; - case 2: - data_type = DSI_DT_GENERIC_READ_2; - cmd[0] = param0; - cmd[1] = param1; - break; - default: - DRM_ERROR("Invalid parameters\n"); - return -EINVAL; - } - - return __read_panel_data(sender, data_type, cmd, sizeof(cmd), - data, len, hs); -} - -int mdfld_dsi_read_mcs(struct mdfld_dsi_pkg_sender *sender, u8 cmd, - u32 *data, u16 len, bool hs) -{ - if (!sender || !data || !len) { - DRM_ERROR("Invalid parameters\n"); - return -EINVAL; - } - - return __read_panel_data(sender, DSI_DT_DCS_READ, &cmd, 1, - data, len, hs); -} - -int mdfld_dsi_write_mem_start(struct mdfld_dsi_pkg_sender *sender) -{ - struct drm_device *dev = sender->dev; - u32 index = 0; - u8 *cb = (u8 *)sender->dbi_cb_addr; - int retry; - - if (!sender) { - DRM_ERROR("Invalid parameter\n"); - return -EINVAL; - } - - if (!sender->dbi_pkg_support) { - DRM_ERROR("No DBI pkg sending on this sender\n"); - return -ENOTSUPP; - } - - if (!spin_trylock(&sender->lock)) - return -EAGAIN; - - /** - * query whether DBI FIFO is empty, - * if not wait it becoming empty - */ - retry = MDFLD_DSI_DBI_FIFO_TIMEOUT; - while (retry && !(REG_READ(sender->mipi_gen_fifo_stat_reg) & BIT(27))) { - udelay(500); - retry--; - } - - /*if DBI FIFO timeout, drop this frame*/ - if (!retry) { - spin_unlock(&sender->lock); - return 0; - } - - *(cb + (index++)) = write_mem_start; - - REG_WRITE(sender->mipi_cmd_len_reg, 1); - REG_WRITE(sender->mipi_cmd_addr_reg, sender->dbi_cb_phy | BIT(0) | BIT(1)); - - retry = MDFLD_DSI_DBI_FIFO_TIMEOUT; - while (retry && (REG_READ(sender->mipi_cmd_addr_reg) & BIT(0))) { - udelay(1); - retry--; - } - - spin_unlock(&sender->lock); - - return 0; -} - -int mdfld_dsi_pkg_sender_init(struct mdfld_dsi_connector * dsi_connector, int pipe) -{ - int ret; - struct mdfld_dsi_pkg_sender * pkg_sender; - struct mdfld_dsi_config * dsi_config = mdfld_dsi_get_config(dsi_connector); - struct drm_device * dev = dsi_config->dev; - struct drm_psb_private * dev_priv = dev->dev_private; - struct psb_gtt * pg = dev_priv->pg; - u32 mipi_val = 0; - - PSB_DEBUG_ENTRY("\n"); - - if(!dsi_connector) { - DRM_ERROR("Invalid parameter\n"); - return -EINVAL; - } - - pkg_sender = dsi_connector->pkg_sender; - - if(!pkg_sender || IS_ERR(pkg_sender)) { - pkg_sender = kzalloc(sizeof(struct mdfld_dsi_pkg_sender), GFP_KERNEL); - if(!pkg_sender) { - DRM_ERROR("Create DSI pkg sender failed\n"); - return -ENOMEM; - } - - dsi_connector->pkg_sender = (void *)pkg_sender; - } - - pkg_sender->dev = dev; - pkg_sender->dsi_connector = dsi_connector; - pkg_sender->pipe = pipe; - pkg_sender->pkg_num = 0; - pkg_sender->panel_mode = 0; - pkg_sender->status = MDFLD_DSI_PKG_SENDER_FREE; - - /*int dbi command buffer*/ - if(dsi_config->type == MDFLD_DSI_ENCODER_DBI) { - pkg_sender->dbi_pkg_support = 1; - ret = mdfld_dbi_cb_init(pkg_sender, pg, pipe); - if(ret) { - DRM_ERROR("DBI command buffer map failed\n"); - goto mapping_err; - } - } - - /*init regs*/ - if(pipe == 0) { - pkg_sender->dpll_reg = PSB_DSI_PLL_CTRL; - pkg_sender->dspcntr_reg = PSB_DSPCNTR(PSB_PIPE_A); - pkg_sender->pipeconf_reg = PSB_PIPECONF(PSB_PIPE_A); - pkg_sender->dsplinoff_reg = PSB_DSPLINOFF(PSB_PIPE_A); - pkg_sender->dspsurf_reg = PSB_DSPSURF(PSB_PIPE_A); - pkg_sender->pipestat_reg = PSB_PIPESTAT(PSB_PIPE_A); - } else if (pipe == 2) { - pkg_sender->dpll_reg = PSB_DSI_PLL_CTRL; - pkg_sender->dspcntr_reg = PSB_DSPCNTR(PSB_PIPE_C); - pkg_sender->pipeconf_reg = PSB_PIPECONF(PSB_PIPE_C); - pkg_sender->dsplinoff_reg = PSB_DSPLINOFF(PSB_PIPE_C); - pkg_sender->dspsurf_reg = PSB_DSPSURF(PSB_PIPE_C); - pkg_sender->pipestat_reg = PSB_PIPESTAT(PSB_PIPE_C); - } - - pkg_sender->mipi_intr_stat_reg = MIPI_INTR_STAT_REG(pipe); - pkg_sender->mipi_lp_gen_data_reg = MIPI_LP_GEN_DATA_REG(pipe); - pkg_sender->mipi_hs_gen_data_reg = MIPI_HS_GEN_DATA_REG(pipe); - pkg_sender->mipi_lp_gen_ctrl_reg = MIPI_LP_GEN_CTRL_REG(pipe); - pkg_sender->mipi_hs_gen_ctrl_reg = MIPI_HS_GEN_CTRL_REG(pipe); - pkg_sender->mipi_gen_fifo_stat_reg = MIPI_GEN_FIFO_STAT_REG(pipe); - pkg_sender->mipi_data_addr_reg = MIPI_DATA_ADD_REG(pipe); - pkg_sender->mipi_data_len_reg = MIPI_DATA_LEN_REG(pipe); - pkg_sender->mipi_cmd_addr_reg = MIPI_CMD_ADD_REG(pipe); - pkg_sender->mipi_cmd_len_reg = MIPI_CMD_LEN_REG(pipe); - - /*init lock*/ - spin_lock_init(&pkg_sender->lock); - - if (get_panel_type(dev, pipe) != TC35876X) { - /** - * For video mode, don't enable DPI timing output here, - * will init the DPI timing output during mode setting. - */ - if (dsi_config->type == MDFLD_DSI_ENCODER_DPI) - mipi_val = PASS_FROM_SPHY_TO_AFE | SEL_FLOPPED_HSTX; - else if (dsi_config->type == MDFLD_DSI_ENCODER_DBI) - mipi_val = PASS_FROM_SPHY_TO_AFE | SEL_FLOPPED_HSTX - | TE_TRIGGER_GPIO_PIN; - else - DRM_ERROR("Bad DSI encoder type\n"); - - if (pipe == 0) - mipi_val |= 0x2; - - REG_WRITE(MIPI_PORT_CONTROL(pipe), mipi_val); - REG_READ(MIPI_PORT_CONTROL(pipe)); - - /* do dsi controller init */ - mdfld_dsi_controller_init(dsi_config, pipe); - } - - PSB_DEBUG_ENTRY("initialized\n"); - - return 0; - -mapping_err: - kfree(pkg_sender); - dsi_connector->pkg_sender = NULL; - - return ret; -} - -void mdfld_dsi_pkg_sender_destroy(struct mdfld_dsi_pkg_sender * sender) -{ - if(!sender || IS_ERR(sender)) - return; - - /*free mapped command buffer*/ - mdfld_dbi_cb_destroy(sender); - - /*free*/ - kfree(sender); - - PSB_DEBUG_ENTRY("destroyed\n"); -} - - diff --git a/drivers/staging/mrst/drv/mdfld_dsi_pkg_sender.c b/drivers/staging/mrst/drv/mdfld_dsi_pkg_sender.c new file mode 120000 index 0000000..e6aef64 --- /dev/null +++ b/drivers/staging/mrst/drv/mdfld_dsi_pkg_sender.c @@ -0,0 +1 @@ +../../mrst.mcg/drv/mdfld_dsi_pkg_sender.c \ No newline at end of file diff --git a/drivers/staging/mrst/drv/mdfld_dsi_pkg_sender.h b/drivers/staging/mrst/drv/mdfld_dsi_pkg_sender.h deleted file mode 100644 index 91b9675..0000000 --- a/drivers/staging/mrst/drv/mdfld_dsi_pkg_sender.h +++ /dev/null @@ -1,99 +0,0 @@ -/* - * Copyright © 2010 Intel Corporation - * - * Permission is hereby granted, free of charge, to any person obtaining a - * copy of this software and associated documentation files (the "Software"), - * to deal in the Software without restriction, including without limitation - * the rights to use, copy, modify, merge, publish, distribute, sublicense, - * and/or sell copies of the Software, and to permit persons to whom the - * Software is furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice (including the next - * paragraph) shall be included in all copies or substantial portions of the - * Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL - * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING - * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER - * DEALINGS IN THE SOFTWARE. - * - * Authors: - * Jackie Li - */ -#ifndef __MDFLD_DSI_PKG_SENDER_H__ -#define __MDFLD_DSI_PKG_SENDER_H__ - -#include - -#define MDFLD_MAX_DCS_PARAM 8 - -struct mdfld_dsi_pkg_sender { - struct drm_device * dev; - struct mdfld_dsi_connector * dsi_connector; - u32 status; - - u32 panel_mode; - - int pipe; - - spinlock_t lock; - - u32 pkg_num; - - int dbi_pkg_support; - - u32 dbi_cb_phy; - void __iomem *dbi_cb_addr; - - /*registers*/ - u32 dpll_reg; - u32 dspcntr_reg; - u32 pipeconf_reg; - u32 pipestat_reg; - u32 dsplinoff_reg; - u32 dspsurf_reg; - - u32 mipi_intr_stat_reg; - u32 mipi_lp_gen_data_reg; - u32 mipi_hs_gen_data_reg; - u32 mipi_lp_gen_ctrl_reg; - u32 mipi_hs_gen_ctrl_reg; - u32 mipi_gen_fifo_stat_reg; - u32 mipi_data_addr_reg; - u32 mipi_data_len_reg; - u32 mipi_cmd_addr_reg; - u32 mipi_cmd_len_reg; -}; - -/*DCS definitions*/ -#define DCS_SOFT_RESET 0x01 -#define DCS_ENTER_SLEEP_MODE 0x10 -#define DCS_EXIT_SLEEP_MODE 0x11 -#define DCS_SET_DISPLAY_OFF 0x28 -#define DCS_SET_DISPLAY_ON 0x29 -#define DCS_SET_COLUMN_ADDRESS 0x2a -#define DCS_SET_PAGE_ADDRESS 0x2b -#define DCS_WRITE_MEM_START 0x2c -#define DCS_SET_TEAR_OFF 0x34 -#define DCS_SET_TEAR_ON 0x35 - -extern int mdfld_dsi_pkg_sender_init(struct mdfld_dsi_connector * dsi_connector, int pipe); -extern void mdfld_dsi_pkg_sender_destroy(struct mdfld_dsi_pkg_sender * sender); -int mdfld_dsi_write_mem_start(struct mdfld_dsi_pkg_sender *sender); -int mdfld_dsi_send_mcs_short(struct mdfld_dsi_pkg_sender *sender, u8 cmd, - u8 param, u8 param_num, bool hs); -int mdfld_dsi_send_mcs_long(struct mdfld_dsi_pkg_sender *sender, u8 *data, - u32 len, bool hs); -int mdfld_dsi_send_gen_short(struct mdfld_dsi_pkg_sender *sender, u8 param0, - u8 param1, u8 param_num, bool hs); -int mdfld_dsi_send_gen_long(struct mdfld_dsi_pkg_sender *sender, u8 *data, - u32 len, bool hs); - -/*read interfaces*/ -int mdfld_dsi_read_mcs(struct mdfld_dsi_pkg_sender *sender, u8 cmd, - u32 *data, u16 len, bool hs); - -#endif diff --git a/drivers/staging/mrst/drv/mdfld_dsi_pkg_sender.h b/drivers/staging/mrst/drv/mdfld_dsi_pkg_sender.h new file mode 120000 index 0000000..60e2fed --- /dev/null +++ b/drivers/staging/mrst/drv/mdfld_dsi_pkg_sender.h @@ -0,0 +1 @@ +../../mrst.mcg/drv/mdfld_dsi_pkg_sender.h \ No newline at end of file diff --git a/drivers/staging/mrst/drv/mdfld_output.c b/drivers/staging/mrst/drv/mdfld_output.c deleted file mode 100644 index dfb5286..0000000 --- a/drivers/staging/mrst/drv/mdfld_output.c +++ /dev/null @@ -1,142 +0,0 @@ -/* - * Copyright (c) 2010 Intel Corporation - * - * Permission is hereby granted, free of charge, to any person obtaining a - * copy of this software and associated documentation files (the "Software"), - * to deal in the Software without restriction, including without limitation - * the rights to use, copy, modify, merge, publish, distribute, sublicensen - * and/or sell copies of the Software, and to permit persons to whom the - * Software is furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice (including the next - * paragraph) shall be included in all copies or substantial portions of the - * Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL - * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING - * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER - * DEALINGS IN THE SOFTWARE. - * - * Authors: - * Thomas Eaton - * Scott Rowe -*/ - -#include -#include "mdfld_output.h" -#include "mdfld_dsi_dbi.h" -#include "mdfld_dsi_dpi.h" -#include "mdfld_dsi_output.h" - -#include "displays/tpo_cmd.h" -#include "displays/tpo_vid.h" -#include "displays/tmd_vid.h" -#include "displays/hdmi.h" -#include "tc35876x-dsi-lvds.h" - -enum panel_type get_panel_type(struct drm_device *dev, int pipe) -{ - struct drm_psb_private *dev_priv = - (struct drm_psb_private *) dev->dev_private; - - return dev_priv->panel_id; -} - -int is_panel_vid_or_cmd(struct drm_device *dev) -{ - struct drm_psb_private *dev_priv = - (struct drm_psb_private *) dev->dev_private; - - int ret = 0; - switch(dev_priv->panel_id) { - case TMD_VID: - case TPO_VID: - case TC35876X: - ret = MDFLD_DSI_ENCODER_DPI; - break; - case TMD_CMD: - case TPO_CMD: - default: - ret = MDFLD_DSI_ENCODER_DBI; - break; - } - return ret; -} - -void mdfld_output_init(struct drm_device* dev) -{ - enum panel_type p_type1, p_type2; - - /* MIPI panel 1 */ - p_type1 = get_panel_type(dev, 0); - init_panel(dev, 0, p_type1); - -#ifdef CONFIG_MDFD_DUAL_MIPI - /* MIPI panel 2 */ - p_type2 = get_panel_type(dev, 2); - init_panel(dev, 2, p_type2); -#endif - -#ifdef CONFIG_MDFD_HDMI - /* HDMI panel */ - init_panel(dev, 1, HDMI); -#endif -} - -void init_panel(struct drm_device* dev, int mipi_pipe, enum panel_type p_type) -{ - struct drm_psb_private *dev_priv = - (struct drm_psb_private *) dev->dev_private; - struct panel_funcs * p_cmd_funcs = NULL; - struct panel_funcs * p_vid_funcs = NULL; - - p_cmd_funcs = kzalloc(sizeof(struct panel_funcs), GFP_KERNEL); - p_vid_funcs = kzalloc(sizeof(struct panel_funcs), GFP_KERNEL); - - switch (p_type) { - case TPO_CMD: - tpo_cmd_init(dev, p_cmd_funcs); - mdfld_dsi_output_init(dev, mipi_pipe, NULL, p_cmd_funcs, NULL); - break; - case TPO_VID: - tpo_vid_init(dev, p_vid_funcs); - mdfld_dsi_output_init(dev, mipi_pipe, NULL, NULL, p_vid_funcs); - break; - case TMD_CMD: - /*tmd_cmd_init(dev, p_cmd_funcs);*/ - mdfld_dsi_output_init(dev, mipi_pipe, NULL, p_cmd_funcs, NULL); - break; - case TC35876X: - tc35876x_init(dev, p_vid_funcs); - mdfld_dsi_output_init(dev, mipi_pipe, NULL, NULL, p_vid_funcs); - break; - case TMD_VID: - tmd_vid_init(dev, p_vid_funcs); - mdfld_dsi_output_init(dev, mipi_pipe, NULL, NULL, p_vid_funcs); - break; - case TPO: /*TPO panel supports both cmd & vid interfaces*/ - tpo_cmd_init(dev, p_cmd_funcs); - tpo_vid_init(dev, p_vid_funcs); - mdfld_dsi_output_init(dev, mipi_pipe, NULL, p_cmd_funcs, p_vid_funcs); - break; - case TMD: - break; - case HDMI: - if (dev_priv && dev_priv->hdmi_present) { - printk(KERN_ALERT "GFX: Initializing HDMI"); - mdfld_hdmi_init(dev, &dev_priv->mode_dev); - } else { - printk(KERN_ERR "HDMI dev priv should not be null" - "at this time!\n"); - BUG(); - } - - break; - default: - break; - } -} - diff --git a/drivers/staging/mrst/drv/mdfld_output.c b/drivers/staging/mrst/drv/mdfld_output.c new file mode 120000 index 0000000..77c2f8f --- /dev/null +++ b/drivers/staging/mrst/drv/mdfld_output.c @@ -0,0 +1 @@ +../../mrst.mcg/drv/mdfld_output.c \ No newline at end of file diff --git a/drivers/staging/mrst/drv/mdfld_output.h b/drivers/staging/mrst/drv/mdfld_output.h deleted file mode 100644 index 876dfd0..0000000 --- a/drivers/staging/mrst/drv/mdfld_output.h +++ /dev/null @@ -1,73 +0,0 @@ -/* - * Copyright (c) 2010 Intel Corporation - * - * Permission is hereby granted, free of charge, to any person obtaining a - * copy of this software and associated documentation files (the "Software"), - * to deal in the Software without restriction, including without limitation - * the rights to use, copy, modify, merge, publish, distribute, sublicensen - * and/or sell copies of the Software, and to permit persons to whom the - * Software is furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice (including the next - * paragraph) shall be included in all copies or substantial portions of the - * Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL - * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING - * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER - * DEALINGS IN THE SOFTWARE. - * - * Authors: - * Thomas Eaton - * Scott Rowe -*/ - - - -#ifndef MDFLD_OUTPUT_H -#define MDFLD_OUTPUT_H - -#include -#include -#include -#include - -#include "psb_drv.h" - -#define TPO_PANEL_WIDTH 84 -#define TPO_PANEL_HEIGHT 46 -#define TMD_PANEL_WIDTH 39 -#define TMD_PANEL_HEIGHT 71 - -struct mdfld_dsi_config; - -struct panel_info { - u32 width_mm; - u32 height_mm; - - /*other infos*/ -}; - -struct panel_funcs { - const struct drm_encoder_funcs* encoder_funcs; - const struct drm_encoder_helper_funcs* encoder_helper_funcs; - struct drm_display_mode* (*get_config_mode)(struct drm_device*); - void (*update_fb)(struct mdfld_dsi_dbi_output*, int); - int (*get_panel_info)(struct drm_device *, int, struct panel_info *); - int (*reset)(int pipe); - void (*drv_ic_init)(struct mdfld_dsi_config *dsi_config, int pipe); -}; - -void mdfld_output_init(struct drm_device* dev); - -void init_panel(struct drm_device* dev, int mipi_pipe, enum panel_type p_type); -enum panel_type get_panel_type(struct drm_device *dev, int pipe); -int is_panel_vid_or_cmd(struct drm_device *dev); - - -#endif - - diff --git a/drivers/staging/mrst/drv/mdfld_output.h b/drivers/staging/mrst/drv/mdfld_output.h new file mode 120000 index 0000000..72b984a --- /dev/null +++ b/drivers/staging/mrst/drv/mdfld_output.h @@ -0,0 +1 @@ +../../mrst.mcg/drv/mdfld_output.h \ No newline at end of file diff --git a/drivers/staging/mrst/drv/tmd_6x10_vid.c b/drivers/staging/mrst/drv/tmd_6x10_vid.c new file mode 120000 index 0000000..d1f3fc9 --- /dev/null +++ b/drivers/staging/mrst/drv/tmd_6x10_vid.c @@ -0,0 +1 @@ +../../mrst.mcg/drv/tmd_6x10_vid.c \ No newline at end of file