diff options
Diffstat (limited to 'drivers/staging/gma500/mdfld_dsi_output.c')
-rw-r--r-- | drivers/staging/gma500/mdfld_dsi_output.c | 250 |
1 files changed, 141 insertions, 109 deletions
diff --git a/drivers/staging/gma500/mdfld_dsi_output.c b/drivers/staging/gma500/mdfld_dsi_output.c index ff75ece9dcf8..3286c3da4d70 100644 --- a/drivers/staging/gma500/mdfld_dsi_output.c +++ b/drivers/staging/gma500/mdfld_dsi_output.c @@ -35,55 +35,18 @@ #define MDFLD_DSI_BRIGHTNESS_MAX_LEVEL 100 -/* get the CABC LABC from command line. */ static int CABC_control = 1; static int LABC_control = 1; -#ifdef MODULE module_param (CABC_control, int, 0644); module_param (LABC_control, int, 0644); -#else -static int __init parse_CABC_control(char *arg) -{ - /* CABC control can be passed in as a cmdline parameter */ - /* to enable this feature add CABC=1 to cmdline */ - /* to disable this feature add CABC=0 to cmdline */ - if (!arg) - return -EINVAL; - - if (!strcasecmp(arg, "0")) - CABC_control = 0; - else if (!strcasecmp (arg, "1")) - CABC_control = 1; - - return 0; -} -early_param ("CABC", parse_CABC_control); - -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. **/ -static u32 mdfld_dbi_mcs_hysteresis[] = { +static const u32 mdfld_dbi_mcs_hysteresis[] = { 0x42000f57, 0x8c006400, 0xff00bf00, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0x38000aff, 0x82005000, 0xff00ab00, 0xffffffff, @@ -91,25 +54,26 @@ static u32 mdfld_dbi_mcs_hysteresis[] = { 0x000000ff, }; -static u32 mdfld_dbi_mcs_display_profile[] = { +static const u32 mdfld_dbi_mcs_display_profile[] = { 0x50281450, 0x0000c882, 0x00000000, 0x00000000, 0x00000000, }; -static u32 mdfld_dbi_mcs_kbbc_profile[] = { +static const u32 mdfld_dbi_mcs_kbbc_profile[] = { 0x00ffcc60, 0x00000000, 0x00000000, 0x00000000, }; -static u32 mdfld_dbi_mcs_gamma_profile[] = { +static const u32 mdfld_dbi_mcs_gamma_profile[] = { 0x81111158, 0x88888888, 0x88888888, }; /* * write hysteresis values. */ -static void mdfld_dsi_write_hysteresis (struct mdfld_dsi_config * dsi_config, int pipe) +static void mdfld_dsi_write_hysteresis (struct mdfld_dsi_config *dsi_config, + int pipe) { - struct mdfld_dsi_pkg_sender * sender = mdfld_dsi_get_pkg_sender(dsi_config); + struct mdfld_dsi_pkg_sender *sender = mdfld_dsi_get_pkg_sender(dsi_config); if(!sender) { WARN_ON(1); @@ -124,9 +88,9 @@ static void mdfld_dsi_write_hysteresis (struct mdfld_dsi_config * dsi_config, in /* * write display profile values. */ -static void mdfld_dsi_write_display_profile (struct mdfld_dsi_config * dsi_config, int pipe) +static void mdfld_dsi_write_display_profile(struct mdfld_dsi_config *dsi_config, int pipe) { - struct mdfld_dsi_pkg_sender * sender = mdfld_dsi_get_pkg_sender(dsi_config); + struct mdfld_dsi_pkg_sender *sender = mdfld_dsi_get_pkg_sender(dsi_config); if(!sender) { WARN_ON(1); @@ -143,7 +107,7 @@ static void mdfld_dsi_write_display_profile (struct mdfld_dsi_config * dsi_confi */ static void mdfld_dsi_write_kbbc_profile (struct mdfld_dsi_config * dsi_config, int pipe) { - struct mdfld_dsi_pkg_sender * sender = mdfld_dsi_get_pkg_sender(dsi_config); + struct mdfld_dsi_pkg_sender *sender = mdfld_dsi_get_pkg_sender(dsi_config); if(!sender) { WARN_ON(1); @@ -155,12 +119,12 @@ static void mdfld_dsi_write_kbbc_profile (struct mdfld_dsi_config * dsi_config, MDFLD_DSI_SEND_PACKAGE); } -/** +/* * write gamma setting. */ -static void mdfld_dsi_write_gamma_setting (struct mdfld_dsi_config * dsi_config, int pipe) +static void mdfld_dsi_write_gamma_setting (struct mdfld_dsi_config *dsi_config, int pipe) { - struct mdfld_dsi_pkg_sender * sender = mdfld_dsi_get_pkg_sender(dsi_config); + struct mdfld_dsi_pkg_sender *sender = mdfld_dsi_get_pkg_sender(dsi_config); if(!sender) { WARN_ON(1); @@ -172,7 +136,7 @@ static void mdfld_dsi_write_gamma_setting (struct mdfld_dsi_config * dsi_config, MDFLD_DSI_SEND_PACKAGE); } -/** +/* * 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) @@ -193,16 +157,16 @@ void mdfld_dsi_gen_fifo_ready (struct drm_device *dev, u32 gen_fifo_stat_reg, u3 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) +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; + 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) { @@ -223,7 +187,7 @@ void mdfld_dsi_brightness_init (struct mdfld_dsi_config * dsi_config, int pipe) 1, MDFLD_DSI_SEND_PACKAGE); - mdfld_dsi_write_hysteresis (dsi_config, pipe); + mdfld_dsi_write_hysteresis(dsi_config, pipe); mdfld_dsi_write_display_profile (dsi_config, pipe); mdfld_dsi_write_kbbc_profile (dsi_config, pipe); mdfld_dsi_write_gamma_setting (dsi_config, pipe); @@ -253,7 +217,7 @@ void mdfld_dsi_brightness_init (struct mdfld_dsi_config * dsi_config, int pipe) MDFLD_DSI_SEND_PACKAGE); } -/** +/* * Manage the mipi display brightness. * TODO: refine this interface later */ @@ -262,8 +226,8 @@ 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; - int p_type = TMD_VID; + u32 gen_ctrl_val; + int p_type; if (!dev || (pipe != 0 && pipe != 2)) { dev_err(dev->dev, "Invalid parameter\n"); @@ -288,7 +252,8 @@ void mdfld_dsi_brightness_control(struct drm_device *dev, int pipe, int level) gen_ctrl_val = ((level * 0xff) / MDFLD_DSI_BRIGHTNESS_MAX_LEVEL) & 0xff; - dev_dbg(dev->dev, "pipe = %d, gen_ctrl_val = %d. \n", pipe, gen_ctrl_val); + dev_dbg(dev->dev, + "pipe = %d, gen_ctrl_val = %d. \n", pipe, gen_ctrl_val); if(p_type == TMD_VID || p_type == TMD_CMD){ /* Set display backlight value */ @@ -344,7 +309,7 @@ void mdfld_dsi_controller_shutdown(struct mdfld_dsi_config * dsi_config, int pip if(!(REG_READ(MIPIA_DEVICE_READY_REG + reg_offset) & DSI_DEVICE_READY)) goto shutdown_out; - /*send shut down package, clean packet send bit first*/ + /* Send shut down package, clean packet send bit first */ if(REG_READ(MIPIA_INTR_STAT_REG + reg_offset) & DSI_INTR_STATE_SPL_PKG_SENT) { REG_WRITE((MIPIA_INTR_STAT_REG + reg_offset), (REG_READ(MIPIA_INTR_STAT_REG + reg_offset) | DSI_INTR_STATE_SPL_PKG_SENT)); @@ -432,6 +397,53 @@ startup_out: gma_power_end(dev); } + +static int mdfld_dsi_get_panel_status(struct mdfld_dsi_config *dsi_config, + u8 dcs, + u32 *data, + u8 transmission) +{ + struct mdfld_dsi_pkg_sender *sender + = mdfld_dsi_get_pkg_sender(dsi_config); + + if (!sender || !data) { + DRM_ERROR("Invalid parameter\n"); + return -EINVAL; + } + + if (transmission == MDFLD_DSI_HS_TRANSMISSION) + return mdfld_dsi_read_mcs_hs(sender, dcs, data, 1); + else if (transmission == MDFLD_DSI_LP_TRANSMISSION) + return mdfld_dsi_read_mcs_lp(sender, dcs, data, 1); + else + return -EINVAL; +} + +int mdfld_dsi_get_power_mode(struct mdfld_dsi_config *dsi_config, + u32 *mode, + u8 transmission) +{ + if (!dsi_config || !mode) { + DRM_ERROR("Invalid parameter\n"); + return -EINVAL; + } + + return mdfld_dsi_get_panel_status(dsi_config, 0x0a, mode, transmission); +} + +int mdfld_dsi_get_diagnostic_result(struct mdfld_dsi_config *dsi_config, + u32 *result, + u8 transmission) +{ + if (!dsi_config || !result) { + DRM_ERROR("Invalid parameter\n"); + return -EINVAL; + } + + return mdfld_dsi_get_panel_status(dsi_config, 0x0f, result, + transmission); +} + /* * NOTE: this function was used by OSPM. * TODO: will be removed later, should work out display interfaces for OSPM @@ -459,14 +471,18 @@ static void mdfld_dsi_connector_restore(struct drm_connector * connector) static enum drm_connector_status mdfld_dsi_connector_detect(struct drm_connector * connector, bool force) { - return connector_status_connected; + struct psb_intel_output *psb_output + = to_psb_intel_output(connector); + struct mdfld_dsi_connector *dsi_connector + = MDFLD_DSI_CONNECTOR(psb_output); + return dsi_connector->status; } -static int mdfld_dsi_connector_set_property(struct drm_connector * connector, - struct drm_property * property, - uint64_t value) +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 drm_encoder *encoder = connector->encoder; if (!strcmp(property->name, "scaling mode") && encoder) { struct psb_intel_crtc * psb_crtc = to_psb_intel_crtc(encoder->crtc); @@ -633,9 +649,12 @@ static void mdfld_dsi_connector_dpms(struct drm_connector *connector, int mode) } /* Then check all display panels + monitors status */ + /* Make sure that the Display (B) sub-system status isn't i3 when + * R/W the DC register, otherwise "Fabric error" issue would occur + * during S0i3 state. */ if(!panel_on && !panel_on2 && !(REG_READ(HDMIB_CONTROL) & HDMIB_PORT_EN)) { - /*request rpm idle*/ + /* Request rpm idle */ if(dev_priv->rpm_enabled) pm_request_idle(&dev->pdev->dev); } @@ -652,8 +671,8 @@ static void mdfld_dsi_connector_dpms(struct drm_connector *connector, int mode) #endif } -static struct drm_encoder * mdfld_dsi_connector_best_encoder( - struct drm_connector * connector) +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); @@ -755,16 +774,6 @@ mdfld_dsi_get_configuration_mode(struct mdfld_dsi_config * dsi_config, int pipe) mode->vtotal = mode->vdisplay + \ ((ti->vblank_hi << 8) | ti->vblank_lo); mode->clock = ti->pixel_clock * 10; - - dev_dbg(dev->dev, "hdisplay is %d\n", mode->hdisplay); - dev_dbg(dev->dev, "vdisplay is %d\n", mode->vdisplay); - dev_dbg(dev->dev, "HSS is %d\n", mode->hsync_start); - dev_dbg(dev->dev, "HSE is %d\n", mode->hsync_end); - dev_dbg(dev->dev, "htotal is %d\n", mode->htotal); - dev_dbg(dev->dev, "VSS is %d\n", mode->vsync_start); - dev_dbg(dev->dev, "VSE is %d\n", mode->vsync_end); - dev_dbg(dev->dev, "vtotal is %d\n", mode->vtotal); - dev_dbg(dev->dev, "clock is %d\n", mode->clock); } else { if(dsi_config->type == MDFLD_DSI_ENCODER_DPI) { if (mdfld_get_panel_type(dev, pipe) == TMD_VID) { @@ -810,6 +819,44 @@ mdfld_dsi_get_configuration_mode(struct mdfld_dsi_config * dsi_config, int pipe) 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); + + return ret; +} + /* * MIPI output init * @dev drm device @@ -819,9 +866,9 @@ mdfld_dsi_get_configuration_mode(struct mdfld_dsi_config * dsi_config, int pipe) * 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, +void mdfld_dsi_output_init(struct drm_device *dev, int pipe, - struct mdfld_dsi_config * config, + struct mdfld_dsi_config *config, struct panel_funcs* p_cmd_funcs, struct panel_funcs* p_vid_funcs) { @@ -869,7 +916,7 @@ void mdfld_dsi_output_init(struct drm_device * dev, dsi_config->changed = 1; dsi_config->dev = dev; - /*init fixed mode basing on DSI config type*/ + /* 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)) @@ -917,12 +964,18 @@ void mdfld_dsi_output_init(struct drm_device * dev, connector->interlace_allowed = false; connector->doublescan_allowed = false; - /*attach properties*/ + /* 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 DBI & DPI encoders*/ - if(p_cmd_funcs) { + /* 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; + } + + /* Init DBI & DPI encoders */ + if (p_cmd_funcs) { encoder = mdfld_dsi_dbi_init(dev, dsi_connector, p_cmd_funcs); if(!encoder) { dev_err(dev->dev, "Create DBI encoder failed\n"); @@ -930,12 +983,6 @@ void mdfld_dsi_output_init(struct drm_device * dev, } encoder->private = dsi_config; dsi_config->encoders[MDFLD_DSI_ENCODER_DBI] = encoder; - if(pipe == 2) - dev_priv->encoder2 = encoder; - - if(pipe == 0) - dev_priv->encoder0 = encoder; - } if(p_vid_funcs) { @@ -946,31 +993,16 @@ void mdfld_dsi_output_init(struct drm_device * dev, } encoder->private = dsi_config; dsi_config->encoders[MDFLD_DSI_ENCODER_DPI] = encoder; - - if(pipe == 2) - dev_priv->encoder2 = encoder; - - if(pipe == 0) - dev_priv->encoder0 = encoder; } drm_sysfs_connector_add(connector); - - /*init DSI package sender on this output*/ - if(mdfld_dsi_pkg_sender_init(dsi_connector, pipe)) { - dev_err(dev->dev, - "Package Sender initialization failed on pipe %d\n", - pipe); - goto dsi_init_err2; - } - - dev_dbg(dev->dev, "successfully\n"); return; /*TODO: add code to destroy outputs on error*/ -dsi_init_err2: - drm_sysfs_connector_remove(connector); dsi_init_err1: + /*destroy sender*/ + mdfld_dsi_pkg_sender_destroy(dsi_connector->pkg_sender); + drm_connector_cleanup(connector); kfree(dsi_config->fixed_mode); kfree(dsi_config); |