From c0c98c62cfa071a4634155722575ee3bac0b2090 Mon Sep 17 00:00:00 2001 From: Randy Xu Date: Tue, 20 Dec 2011 09:10:12 +0800 Subject: [PATCH] [Graphics/Display]: Port some patches from HC/DDK1.7 branch BZ: 17881 GFX-Display-Enable-DSR-POC-with-runtime_pm-support.patch GFX-DISPLAY-Add-support-to-CMI-video-mode-MIPI-disp.patch GFX-DISPLAY-Add-supports-for-CMI-720p-command-mode.patch Change-Id: I7602bab208bb2ea7648ec7e772bc834667a63665 Signed-off-by: Randy Xu Reviewed-on: http://android.intel.com:8080/29176 Reviewed-by: buildbot Tested-by: buildbot --- drivers/staging/mrst/drv/displays/h8c7_cmd.h | 49 ++ drivers/staging/mrst/drv/displays/h8c7_vid.h | 39 ++ drivers/staging/mrst/drv/displays/tmd_6x10_vid.h | 5 - drivers/staging/mrst/drv/h8c7_cmd.c | 247 ++++++++ drivers/staging/mrst/drv/h8c7_vid.c | 639 +++++++++++++++++++++ drivers/staging/mrst/drv/mdfld_dsi_dbi.c | 371 +++++++++++- drivers/staging/mrst/drv/mdfld_dsi_dbi.h | 6 + drivers/staging/mrst/drv/mdfld_dsi_dpi.c | 35 +- drivers/staging/mrst/drv/mdfld_dsi_dpi.h | 3 - drivers/staging/mrst/drv/mdfld_dsi_output.c | 37 +- drivers/staging/mrst/drv/mdfld_dsi_output.h | 6 +- drivers/staging/mrst/drv/mdfld_dsi_pkg_sender.c | 54 +- drivers/staging/mrst/drv/mdfld_output.c | 19 +- drivers/staging/mrst/drv/mdfld_output.h | 2 + drivers/staging/mrst/drv/psb_bl.c | 9 +- drivers/staging/mrst/drv/psb_drv.c | 58 +- drivers/staging/mrst/drv/psb_drv.h | 10 + drivers/staging/mrst/drv/psb_intel_display2.c | 12 +- drivers/staging/mrst/drv/psb_powermgmt.c | 114 ++-- drivers/staging/mrst/drv/pyr_cmd.c | 4 + drivers/staging/mrst/drv/tmd_6x10_vid.c | 6 +- drivers/staging/mrst/drv/tmd_vid.c | 2 +- drivers/staging/mrst/drv/tpo_cmd.c | 380 +----------- drivers/staging/mrst/drv/tpo_vid.c | 2 +- drivers/staging/mrst/medfield/Makefile | 2 + .../linux_framebuffer_drm/drmlfb_displayclass.c | 29 + 26 files changed, 1621 insertions(+), 519 deletions(-) create mode 100644 drivers/staging/mrst/drv/displays/h8c7_cmd.h create mode 100644 drivers/staging/mrst/drv/displays/h8c7_vid.h create mode 100755 drivers/staging/mrst/drv/h8c7_cmd.c create mode 100755 drivers/staging/mrst/drv/h8c7_vid.c diff --git a/drivers/staging/mrst/drv/displays/h8c7_cmd.h b/drivers/staging/mrst/drv/displays/h8c7_cmd.h new file mode 100644 index 0000000..235a618 --- /dev/null +++ b/drivers/staging/mrst/drv/displays/h8c7_cmd.h @@ -0,0 +1,49 @@ +/* + * 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: + * Jim Liu +*/ + + +#ifndef H8_C7_CMD_H +#define H8_C7_CMD_H + +#include +#include +#include +#include + +#include "mdfld_output.h" + +struct drm_display_mode *h8c7_get_config_mode(struct drm_device *dev); +int h8c7_get_panel_info(struct drm_device *dev, + int pipe, + struct panel_info *pi); +int mdfld_dsi_h8c7_panel_reset(struct mdfld_dsi_config *dsi_config, + int reset_from); +int mdfld_dsi_h8c7_detect(struct mdfld_dsi_config *dsi_config, + int pipe); +int mdfld_dsi_h8c7_set_brightness(struct mdfld_dsi_config *dsi_config, + int level); +void h8c7_cmd_init(struct drm_device *dev, struct panel_funcs *p_funcs); +#endif diff --git a/drivers/staging/mrst/drv/displays/h8c7_vid.h b/drivers/staging/mrst/drv/displays/h8c7_vid.h new file mode 100644 index 0000000..9943818 --- /dev/null +++ b/drivers/staging/mrst/drv/displays/h8c7_vid.h @@ -0,0 +1,39 @@ +/* + * 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: + * Jim Liu +*/ + + +#ifndef H8_C7_VID_H +#define H8_C7_VID_H + +#include +#include +#include +#include + +#include "mdfld_output.h" + +void h8c7_vid_init(struct drm_device *dev, struct panel_funcs *p_funcs); +#endif diff --git a/drivers/staging/mrst/drv/displays/tmd_6x10_vid.h b/drivers/staging/mrst/drv/displays/tmd_6x10_vid.h index b278939..c3b885e 100755 --- a/drivers/staging/mrst/drv/displays/tmd_6x10_vid.h +++ b/drivers/staging/mrst/drv/displays/tmd_6x10_vid.h @@ -37,9 +37,4 @@ #include "mdfld_output.h" void tmd_6x10_vid_init(struct drm_device *dev, struct panel_funcs *p_funcs); -struct drm_display_mode *tmd_6x10_vid_get_config_mode(struct drm_device *dev); -void mdfld_tmd_6X10_bkl_control(struct mdfld_dsi_config *dsi_config, - u32 pipe, - int level); - #endif diff --git a/drivers/staging/mrst/drv/h8c7_cmd.c b/drivers/staging/mrst/drv/h8c7_cmd.c new file mode 100755 index 0000000..060e4ca --- /dev/null +++ b/drivers/staging/mrst/drv/h8c7_cmd.c @@ -0,0 +1,247 @@ +/* + * 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 + * Jim Liu +*/ + +#include "displays/h8c7_cmd.h" +#include "mdfld_dsi_dbi.h" +#include "mdfld_dsi_dbi_dpu.h" +#include "mdfld_dsi_pkg_sender.h" + +/* ************************************************************************* *\ + * FUNCTION: mdfld_h8c7_dbi_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 u32 h8c7_exit_sleep_mode[] = {0x00000011}; +static u32 h8c7_mcs_protect_off[] = {0x9283ffb9}; +static u32 h8c7_set_tear_on[] = {0x00000035}; +static u32 h8c7_set_full_brightness[] = {0x0000ff51}; +static u32 h8c7_turn_on_backlight[] = {0x00002453}; +static u32 h8c7_disable_cabc[] = {0x00000055}; +static u32 h8c7_ic_bias_current[] = {0x826005bf, 0x00000000}; +static u32 h8c7_set_power[] = {0x44007cb1, 0x0d0d0024, 0x3f3f1a12, 0x00007242}; +static u32 h8c7_set_disp_reg[] = {0x05c80fb2, 0x0084080f, 0x040f05ff, 0x00000020}; +static u32 h8c7_set_command_cyc[] = {0x050000b4, 0x1605a000, 0x1603309d, + 0x00030300, 0x0707061b, 0x00000000}; +static u32 h8c7_set_mipi_ctrl[] = {0x008312ba}; +static u32 h8c7_command_mode[] = {0x000008c2}; +static u32 h8c7_set_blanking_opt_2[] = {0x004000c7}; +static u32 h8c7_set_panel[] = {0x000008cc}; +static u32 h8c7_set_eq_func_ltps[] = {0x00000cd4}; +static u32 h8c7_set_ltps_ctrl_output[] = {0x080800d5, 0x66554400, 0xcccccc77, + 0x667700cc, 0xcccc4455, 0x0000cccc}; +static u32 h8c7_set_video_cyc[] = {0x040000d8, 0x1604a000, 0x1603309d, + 0x00030300, 0x0707061b, 0x00000000}; +static u32 h8c7_gamma_r[] = {0x3c3e3ae0, 0x3332312f, 0x0c080446, 0x110f100d, + 0x3e3a1710, 0x32312f3c, 0x08044633, 0x0f100d0c, 0x00171011}; +static u32 h8c7_gamma_g[] = {0x3d3e3be1, 0x33323131, 0x0b070346, 0x110e100d, + 0x3e3b1710, 0x3231313d, 0x07034633, 0x0e100d0b, 0x00171011}; +static u32 h8c7_gamma_b[] = {0x070601e2, 0x1f322a2d, 0x0e0c0540, 0x13121411, + 0x0601180f, 0x322a2d07, 0x0c05401f, 0x1214110e, 0x00180f13}; + +static u32 h8c7_mcs_protect_on[] = {0x000000b9}; +static u32 h8c7_set_address_mode[] = {0x00000036}; +static u32 h8c7_set_pixel_format[] = {0x0000703a}; + +static void mdfld_h8c7_dbi_ic_init(struct mdfld_dsi_config *dsi_config, int pipe) +{ + struct mdfld_dsi_pkg_sender *sender + = mdfld_dsi_get_pkg_sender(dsi_config); + unsigned long wait_timeout; + + if (!sender) { + DRM_ERROR("Cannot get sender\n"); + return; + } + + PSB_DEBUG_ENTRY("\n"); + + /*wait for 5ms*/ + wait_timeout = jiffies + (HZ / 200); + while (time_before_eq(jiffies, wait_timeout)) + cpu_relax(); + + /* sleep out and wait for 150ms. */ + mdfld_dsi_send_mcs_long_hs(sender, h8c7_exit_sleep_mode, 1, 0); + wait_timeout = jiffies + (3 * HZ / 20); + while (time_before_eq(jiffies, wait_timeout)) + cpu_relax(); + + /* set password and wait for 10ms. */ + mdfld_dsi_send_gen_long_hs(sender, h8c7_mcs_protect_off, 1, 0); + wait_timeout = jiffies + (HZ / 100); + while (time_before_eq(jiffies, wait_timeout)) + cpu_relax(); + + /* set TE on and wait for 10ms. */ + mdfld_dsi_send_mcs_long_hs(sender, h8c7_set_tear_on, 1, 0); + wait_timeout = jiffies + (HZ / 100); + while (time_before_eq(jiffies, wait_timeout)) + cpu_relax(); + + /* set backlight to full brightness and wait for 10ms. */ + mdfld_dsi_send_mcs_long_hs(sender, h8c7_set_full_brightness, 1, 0); + wait_timeout = jiffies + (HZ / 100); + while (time_before_eq(jiffies, wait_timeout)) + cpu_relax(); + + /* set backlight on and wait for 10ms. */ + mdfld_dsi_send_mcs_long_hs(sender, h8c7_turn_on_backlight, 1, 0); + wait_timeout = jiffies + (HZ / 100); + while (time_before_eq(jiffies, wait_timeout)) + cpu_relax(); + + /* disalble CABC and wait for 10ms. */ + mdfld_dsi_send_mcs_long_hs(sender, h8c7_disable_cabc, 1, 0); + wait_timeout = jiffies + (HZ / 100); + while (time_before_eq(jiffies, wait_timeout)) + cpu_relax(); + + mdfld_dsi_send_gen_long_hs(sender, h8c7_ic_bias_current, 2, 0); + wait_timeout = jiffies + (HZ / 100); + while (time_before_eq(jiffies, wait_timeout)) + cpu_relax(); + + mdfld_dsi_send_gen_long_hs(sender, h8c7_set_power, 4, 0); + wait_timeout = jiffies + (HZ / 100); + while (time_before_eq(jiffies, wait_timeout)) + cpu_relax(); + + mdfld_dsi_send_gen_long_hs(sender, h8c7_set_disp_reg, 4, 0); + wait_timeout = jiffies + (HZ / 100); + while (time_before_eq(jiffies, wait_timeout)) + cpu_relax(); + + mdfld_dsi_send_gen_long_hs(sender, h8c7_set_command_cyc, 6, 0); + wait_timeout = jiffies + (HZ / 100); + while (time_before_eq(jiffies, wait_timeout)) + cpu_relax(); + + mdfld_dsi_send_gen_long_hs(sender, h8c7_set_mipi_ctrl, 1, 0); + wait_timeout = jiffies + (HZ / 100); + while (time_before_eq(jiffies, wait_timeout)) + cpu_relax(); + + mdfld_dsi_send_gen_long_hs(sender, h8c7_command_mode, 1, 0); + wait_timeout = jiffies + (HZ / 100); + while (time_before_eq(jiffies, wait_timeout)) + cpu_relax(); + + mdfld_dsi_send_gen_long_hs(sender, h8c7_set_blanking_opt_2, 1, 0); + wait_timeout = jiffies + (HZ / 100); + while (time_before_eq(jiffies, wait_timeout)) + cpu_relax(); + + mdfld_dsi_send_gen_long_hs(sender, h8c7_set_panel, 1, 0); + wait_timeout = jiffies + (HZ / 100); + while (time_before_eq(jiffies, wait_timeout)) + cpu_relax(); + + mdfld_dsi_send_gen_long_hs(sender, h8c7_set_eq_func_ltps, 1, 0); + wait_timeout = jiffies + (HZ / 100); + while (time_before_eq(jiffies, wait_timeout)) + cpu_relax(); + + mdfld_dsi_send_gen_long_hs(sender, h8c7_set_ltps_ctrl_output, 6, 0); + wait_timeout = jiffies + (HZ / 100); + while (time_before_eq(jiffies, wait_timeout)) + cpu_relax(); + + mdfld_dsi_send_gen_long_hs(sender, h8c7_set_video_cyc, 6, 0); + wait_timeout = jiffies + (HZ / 100); + while (time_before_eq(jiffies, wait_timeout)) + cpu_relax(); + + mdfld_dsi_send_gen_long_hs(sender, h8c7_gamma_r, 9, 0); + wait_timeout = jiffies + (HZ / 100); + while (time_before_eq(jiffies, wait_timeout)) + cpu_relax(); + + mdfld_dsi_send_gen_long_hs(sender, h8c7_gamma_g, 9, 0); + wait_timeout = jiffies + (HZ / 100); + while (time_before_eq(jiffies, wait_timeout)) + cpu_relax(); + + mdfld_dsi_send_gen_long_hs(sender, h8c7_gamma_b, 9, 0); + wait_timeout = jiffies + (HZ / 100); + while (time_before_eq(jiffies, wait_timeout)) + cpu_relax(); + + /* disable password and wait for 10ms. */ + mdfld_dsi_send_gen_long_hs(sender, h8c7_mcs_protect_on, 1, 0); + wait_timeout = jiffies + (HZ / 100); + while (time_before_eq(jiffies, wait_timeout)) + cpu_relax(); + + mdfld_dsi_send_mcs_long_hs(sender, h8c7_set_address_mode, 1, 0); + wait_timeout = jiffies + (HZ / 100); + while (time_before_eq(jiffies, wait_timeout)) + cpu_relax(); + + mdfld_dsi_send_mcs_long_hs(sender, h8c7_set_pixel_format, 1, 0); + wait_timeout = jiffies + (HZ / 100); + while (time_before_eq(jiffies, wait_timeout)) + cpu_relax(); +} + +/* H8C7 DBI encoder helper funcs*/ +static const struct drm_encoder_helper_funcs mdfld_h8c7_dbi_helper_funcs = { + .dpms = mdfld_dsi_dbi_dpms, + .mode_fixup = mdfld_dsi_mode_fixup, + .prepare = mdfld_dsi_dbi_prepare, + .mode_set = mdfld_dsi_dbi_mode_set, + .commit = mdfld_dsi_dbi_commit, +}; + +/*H8C7 DBI encoder funcs*/ +static const struct drm_encoder_funcs mdfld_h8c7_dbi_encoder_funcs = { + .destroy = drm_encoder_cleanup, +}; + +void h8c7_cmd_init(struct drm_device* dev, struct panel_funcs* p_funcs) +{ + if (!dev || !p_funcs) { + DRM_ERROR("Invalid parameters\n"); + return; + } + + PSB_DEBUG_ENTRY("\n"); + + p_funcs->encoder_funcs = &mdfld_h8c7_dbi_encoder_funcs; + p_funcs->encoder_helper_funcs = &mdfld_h8c7_dbi_helper_funcs; + p_funcs->get_config_mode = &h8c7_get_config_mode; + p_funcs->update_fb = mdfld_dsi_dbi_update_fb; + p_funcs->get_panel_info = h8c7_get_panel_info; + p_funcs->reset = mdfld_dsi_h8c7_panel_reset; + p_funcs->drv_ic_init = mdfld_h8c7_dbi_ic_init; + p_funcs->detect = mdfld_dsi_h8c7_detect; +// p_funcs->set_brightness = mdfld_dsi_tpo_cmd_set_brightness; + p_funcs->set_brightness = mdfld_dsi_h8c7_set_brightness; +} diff --git a/drivers/staging/mrst/drv/h8c7_vid.c b/drivers/staging/mrst/drv/h8c7_vid.c new file mode 100755 index 0000000..edeaee9 --- /dev/null +++ b/drivers/staging/mrst/drv/h8c7_vid.c @@ -0,0 +1,639 @@ +/* + * 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 "displays/h8c7_vid.h" +#include "mdfld_dsi_dpi.h" +#include "mdfld_dsi_pkg_sender.h" + +/* ************************************************************************* *\ + * FUNCTION: mdfld_h8c7_dpi_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 u32 h8c7_exit_sleep_mode[] = {0x00000011}; +static u32 h8c7_mcs_protect_off[] = {0x9283ffb9}; +static u32 h8c7_set_tear_on[] = {0x00000035}; +static u32 h8c7_set_brightness[] = {0x00000051}; +static u32 h8c7_set_full_brightness[] = {0x0000ff51}; +static u32 h8c7_turn_on_backlight[] = {0x00002453}; +static u32 h8c7_disable_cabc[] = {0x00000055}; +static u32 h8c7_ic_bias_current[] = {0x826005bf, 0x00000000}; +static u32 h8c7_set_power[] = {0x44007cb1, 0x0d0d0024, 0x3f3f1a12, 0x00007242}; +static u32 h8c7_set_disp_reg[] = {0x05c80fb2, 0x0084080f, 0x040f05ff, 0x00000020}; +static u32 h8c7_set_command_cyc[] = {0x050000b4, 0x1605a000, 0x1603309d, + 0x00030300, 0x0707061b, 0x00000000}; +static u32 h8c7_set_mipi_ctrl[] = {0x008312ba}; +static u32 h8c7_video_mode[] = {0x000003c2}; +static u32 h8c7_set_blanking_opt_2[] = {0x004000c7}; +static u32 h8c7_set_panel[] = {0x000008cc}; +static u32 h8c7_set_eq_func_ltps[] = {0x00000cd4}; +static u32 h8c7_set_ltps_ctrl_output[] = {0x080800d5, 0x66554400, 0xcccccc77, + 0x667700cc, 0xcccc4455, 0x0000cccc}; +static u32 h8c7_set_video_cyc[] = {0x040000d8, 0x1604a000, 0x1603309d, + 0x00030300, 0x0707061b, 0x00000000}; +static u32 h8c7_gamma_r[] = {0x3c3e3ae0, 0x3332312f, 0x0c080446, 0x110f100d, + 0x3e3a1710, 0x32312f3c, 0x08044633, 0x0f100d0c, 0x00171011}; +static u32 h8c7_gamma_g[] = {0x3d3e3be1, 0x33323131, 0x0b070346, 0x110e100d, + 0x3e3b1710, 0x3231313d, 0x07034633, 0x0e100d0b, 0x00171011}; +static u32 h8c7_gamma_b[] = {0x070601e2, 0x1f322a2d, 0x0e0c0540, 0x13121411, + 0x0601180f, 0x322a2d07, 0x0c05401f, 0x1214110e, 0x00180f13}; + +static u32 h8c7_mcs_protect_on[] = {0x000000b9}; +static u32 h8c7_set_address_mode[] = {0x00000036}; +static u32 h8c7_set_pixel_format[] = {0x0000703a}; +static u32 h8c7_set_display_on[] = {0x00000029}; +static u32 h8c7_set_display_off[] = {0x00000028}; +static u32 h8c7_enter_sleep_mode[] = {0x00000010}; + +static void mdfld_h8c7_dpi_ic_init(struct mdfld_dsi_config *dsi_config, int pipe) +{ + struct mdfld_dsi_pkg_sender *sender + = mdfld_dsi_get_pkg_sender(dsi_config); + unsigned long wait_timeout; + + if (!sender) { + DRM_ERROR("Cannot get sender\n"); + return; + } + + PSB_DEBUG_ENTRY("\n"); + + /*wait for 5ms*/ + wait_timeout = jiffies + (HZ / 200); + while (time_before_eq(jiffies, wait_timeout)) + cpu_relax(); + + /* sleep out and wait for 150ms. */ + mdfld_dsi_send_mcs_long_hs(sender, h8c7_exit_sleep_mode, 1, 0); + wait_timeout = jiffies + (3 * HZ / 20); + while (time_before_eq(jiffies, wait_timeout)) + cpu_relax(); + + /* set password and wait for 10ms. */ + mdfld_dsi_send_gen_long_hs(sender, h8c7_mcs_protect_off, 1, 0); + wait_timeout = jiffies + (HZ / 100); + while (time_before_eq(jiffies, wait_timeout)) + cpu_relax(); + + /* set TE on and wait for 10ms. */ + mdfld_dsi_send_mcs_long_hs(sender, h8c7_set_tear_on, 1, 0); + wait_timeout = jiffies + (HZ / 100); + while (time_before_eq(jiffies, wait_timeout)) + cpu_relax(); + + /* set backlight to full brightness and wait for 10ms. */ + mdfld_dsi_send_mcs_long_hs(sender, h8c7_set_full_brightness, 1, 0); + wait_timeout = jiffies + (HZ / 100); + while (time_before_eq(jiffies, wait_timeout)) + cpu_relax(); + + /* set backlight on and wait for 10ms. */ + mdfld_dsi_send_mcs_long_hs(sender, h8c7_turn_on_backlight, 1, 0); + wait_timeout = jiffies + (HZ / 100); + while (time_before_eq(jiffies, wait_timeout)) + cpu_relax(); + + /* disalble CABC and wait for 10ms. */ + mdfld_dsi_send_mcs_long_hs(sender, h8c7_disable_cabc, 1, 0); + wait_timeout = jiffies + (HZ / 100); + while (time_before_eq(jiffies, wait_timeout)) + cpu_relax(); + + mdfld_dsi_send_gen_long_hs(sender, h8c7_ic_bias_current, 2, 0); + wait_timeout = jiffies + (HZ / 100); + while (time_before_eq(jiffies, wait_timeout)) + cpu_relax(); + + mdfld_dsi_send_gen_long_hs(sender, h8c7_set_power, 4, 0); + wait_timeout = jiffies + (HZ / 100); + while (time_before_eq(jiffies, wait_timeout)) + cpu_relax(); + + mdfld_dsi_send_gen_long_hs(sender, h8c7_set_disp_reg, 4, 0); + wait_timeout = jiffies + (HZ / 100); + while (time_before_eq(jiffies, wait_timeout)) + cpu_relax(); + + mdfld_dsi_send_gen_long_hs(sender, h8c7_set_command_cyc, 6, 0); + wait_timeout = jiffies + (HZ / 100); + while (time_before_eq(jiffies, wait_timeout)) + cpu_relax(); + + mdfld_dsi_send_gen_long_hs(sender, h8c7_set_mipi_ctrl, 1, 0); + wait_timeout = jiffies + (HZ / 100); + while (time_before_eq(jiffies, wait_timeout)) + cpu_relax(); + + mdfld_dsi_send_gen_long_hs(sender, h8c7_video_mode, 1, 0); + wait_timeout = jiffies + (HZ / 100); + while (time_before_eq(jiffies, wait_timeout)) + cpu_relax(); + + mdfld_dsi_send_gen_long_hs(sender, h8c7_set_blanking_opt_2, 1, 0); + wait_timeout = jiffies + (HZ / 100); + while (time_before_eq(jiffies, wait_timeout)) + cpu_relax(); + + mdfld_dsi_send_gen_long_hs(sender, h8c7_set_panel, 1, 0); + wait_timeout = jiffies + (HZ / 100); + while (time_before_eq(jiffies, wait_timeout)) + cpu_relax(); + + mdfld_dsi_send_gen_long_hs(sender, h8c7_set_eq_func_ltps, 1, 0); + wait_timeout = jiffies + (HZ / 100); + while (time_before_eq(jiffies, wait_timeout)) + cpu_relax(); + + mdfld_dsi_send_gen_long_hs(sender, h8c7_set_ltps_ctrl_output, 6, 0); + wait_timeout = jiffies + (HZ / 100); + while (time_before_eq(jiffies, wait_timeout)) + cpu_relax(); + + mdfld_dsi_send_gen_long_hs(sender, h8c7_set_video_cyc, 6, 0); + wait_timeout = jiffies + (HZ / 100); + while (time_before_eq(jiffies, wait_timeout)) + cpu_relax(); + + mdfld_dsi_send_gen_long_hs(sender, h8c7_gamma_r, 9, 0); + wait_timeout = jiffies + (HZ / 100); + while (time_before_eq(jiffies, wait_timeout)) + cpu_relax(); + + mdfld_dsi_send_gen_long_hs(sender, h8c7_gamma_g, 9, 0); + wait_timeout = jiffies + (HZ / 100); + while (time_before_eq(jiffies, wait_timeout)) + cpu_relax(); + + mdfld_dsi_send_gen_long_hs(sender, h8c7_gamma_b, 9, 0); + wait_timeout = jiffies + (HZ / 100); + while (time_before_eq(jiffies, wait_timeout)) + cpu_relax(); + + /* disable password and wait for 10ms. */ + mdfld_dsi_send_gen_long_hs(sender, h8c7_mcs_protect_on, 1, 0); + wait_timeout = jiffies + (HZ / 100); + while (time_before_eq(jiffies, wait_timeout)) + cpu_relax(); + + mdfld_dsi_send_mcs_long_hs(sender, h8c7_set_address_mode, 1, 0); + wait_timeout = jiffies + (HZ / 100); + while (time_before_eq(jiffies, wait_timeout)) + cpu_relax(); + + mdfld_dsi_send_mcs_long_hs(sender, h8c7_set_pixel_format, 1, 0); + wait_timeout = jiffies + (HZ / 100); + while (time_before_eq(jiffies, wait_timeout)) + cpu_relax(); +} + +static void +mdfld_h8c7_dpi_controller_init(struct mdfld_dsi_config *dsi_config, + int pipe, int update) +{ + struct mdfld_dsi_hw_context *hw_ctx = + &dsi_config->dsi_hw_context; + struct drm_device *dev = dsi_config->dev; + int lane_count = dsi_config->lane_count; + u32 mipi_control_reg = dsi_config->regs.mipi_control_reg; + u32 intr_en_reg = dsi_config->regs.intr_en_reg; + u32 hs_tx_timeout_reg = dsi_config->regs.hs_tx_timeout_reg; + u32 lp_rx_timeout_reg = dsi_config->regs.lp_rx_timeout_reg; + u32 turn_around_timeout_reg = + dsi_config->regs.turn_around_timeout_reg; + u32 device_reset_timer_reg = + dsi_config->regs.device_reset_timer_reg; + u32 high_low_switch_count_reg = + dsi_config->regs.high_low_switch_count_reg; + u32 init_count_reg = dsi_config->regs.init_count_reg; + u32 eot_disable_reg = dsi_config->regs.eot_disable_reg; + u32 lp_byteclk_reg = dsi_config->regs.lp_byteclk_reg; + u32 clk_lane_switch_time_cnt_reg = + dsi_config->regs.clk_lane_switch_time_cnt_reg; + u32 video_mode_format_reg = + dsi_config->regs.video_mode_format_reg; + u32 dphy_param_reg = dsi_config->regs.dphy_param_reg; + u32 dsi_func_prg_reg = dsi_config->regs.dsi_func_prg_reg; + + PSB_DEBUG_ENTRY("%s: initializing dsi controller on pipe %d\n", + __func__, pipe); + + hw_ctx->mipi_control = 0x18; + hw_ctx->intr_en = 0xffffffff; + hw_ctx->hs_tx_timeout = 0xffffff; + hw_ctx->lp_rx_timeout = 0xffffff; + hw_ctx->turn_around_timeout = 0x14; + hw_ctx->device_reset_timer = 0xff; + hw_ctx->high_low_switch_count = 0x25; + hw_ctx->init_count = 0xf0; + hw_ctx->eot_disable = 0x0; + hw_ctx->lp_byteclk = 0x4; + hw_ctx->clk_lane_switch_time_cnt = 0xa0014; + hw_ctx->dphy_param = 0x150a600f; + + /*setup video mode format*/ + hw_ctx->video_mode_format = 0xf; + + /*set up func_prg*/ + hw_ctx->dsi_func_prg = (0x200 | lane_count); + + if (update) { + REG_WRITE(dphy_param_reg, hw_ctx->dphy_param); + REG_WRITE(mipi_control_reg, hw_ctx->mipi_control); + REG_WRITE(intr_en_reg, hw_ctx->intr_en); + REG_WRITE(hs_tx_timeout_reg, hw_ctx->hs_tx_timeout); + REG_WRITE(lp_rx_timeout_reg, hw_ctx->lp_rx_timeout); + REG_WRITE(turn_around_timeout_reg, hw_ctx->turn_around_timeout); + REG_WRITE(device_reset_timer_reg, hw_ctx->device_reset_timer); + REG_WRITE(high_low_switch_count_reg, + hw_ctx->high_low_switch_count); + REG_WRITE(init_count_reg, hw_ctx->init_count); + REG_WRITE(eot_disable_reg, hw_ctx->eot_disable); + REG_WRITE(lp_byteclk_reg, hw_ctx->lp_byteclk); + REG_WRITE(clk_lane_switch_time_cnt_reg, + hw_ctx->clk_lane_switch_time_cnt); + REG_WRITE(video_mode_format_reg, hw_ctx->video_mode_format); + REG_WRITE(dsi_func_prg_reg, hw_ctx->dsi_func_prg); + } +} + +int mdfld_dsi_h8c7_detect(struct mdfld_dsi_config *dsi_config, + int pipe) +{ + int status; + struct drm_device *dev = dsi_config->dev; + + printk(KERN_ALERT"%s\n", __func__); + + if (pipe == 0) { + /*reconfig lane configuration*/ + dsi_config->lane_count = 3; + dsi_config->lane_config = MDFLD_DSI_DATA_LANE_4_0; + dsi_config->dsi_hw_context.pll_bypass_mode = 1; + /* This is for 400 mhz. Set it to 0 for 800mhz */ + dsi_config->dsi_hw_context.cck_div = 1; + + if (IS_CTP(dev)) + dsi_config->dsi_hw_context.pll_bypass_mode = 0; + + status = MDFLD_DSI_PANEL_CONNECTED; + } else { + PSB_DEBUG_ENTRY("Only support single panel\n"); + status = MDFLD_DSI_PANEL_DISCONNECTED; + } + + return status; +} + +static int +mdfld_h8c7_get_power_state(struct mdfld_dsi_config *dsi_config, + int pipe) +{ + struct mdfld_dsi_hw_registers *regs; + struct mdfld_dsi_hw_context *ctx; + struct drm_device *dev; + int powerstatus = 0; + + PSB_DEBUG_ENTRY("Getting power state..."); + + if (!dsi_config) + return -EINVAL; + + regs = &dsi_config->regs; + ctx = &dsi_config->dsi_hw_context; + dev = dsi_config->dev; + + /* for get date from panel side is not easy, + so here use display side setting to judge + wheather panel have enabled or not */ + if ((REG_READ(regs->dpll_reg) & BIT31) && + (REG_READ(regs->pipeconf_reg) & BIT30) && + (REG_READ(regs->mipi_reg) & BIT31)) + powerstatus = MDFLD_DSI_PANEL_POWER_ON; + else + powerstatus = MDFLD_DSI_PANEL_POWER_OFF; + + PSB_DEBUG_ENTRY("Getting power state...%s", + powerstatus ? "OFF" : "ON"); + return powerstatus; +} + +static int mdfld_dsi_h8c7_power_on(struct mdfld_dsi_config *dsi_config) +{ + struct mdfld_dsi_pkg_sender *sender = + mdfld_dsi_get_pkg_sender(dsi_config); + unsigned long wait_timeout; + int err; + + PSB_DEBUG_ENTRY("Turn on video mode TMD panel...\n"); + + if (!sender) { + DRM_ERROR("Failed to get DSI packet sender\n"); + return -EINVAL; + } + + /* sleep out and wait for 150ms. */ + mdfld_dsi_send_mcs_long_hs(sender, h8c7_exit_sleep_mode, 1, 0); + wait_timeout = jiffies + (3 * HZ / 20); + while (time_before_eq(jiffies, wait_timeout)) + cpu_relax(); + + /*set display on*/ + mdfld_dsi_send_mcs_long_hs(sender, h8c7_set_display_on, 1, 0); + wait_timeout = jiffies + (HZ / 100); + while (time_before_eq(jiffies, wait_timeout)) + cpu_relax(); + + /* FIXME Enable CABC later*/ + + /*send TURN_ON packet*/ + err = mdfld_dsi_send_dpi_spk_pkg_hs(sender, + MDFLD_DSI_DPI_SPK_TURN_ON); + if (err) { + DRM_ERROR("Failed to send turn on packet\n"); + return err; + } + + return 0; +} + +static int mdfld_dsi_h8c7_power_off(struct mdfld_dsi_config *dsi_config) +{ + struct mdfld_dsi_pkg_sender *sender = + mdfld_dsi_get_pkg_sender(dsi_config); + unsigned long wait_timeout; + int err; + + PSB_DEBUG_ENTRY("Turn off video mode TMD panel...\n"); + + if (!sender) { + DRM_ERROR("Failed to get DSI packet sender\n"); + return -EINVAL; + } + + /*send SHUT_DOWN packet*/ + err = mdfld_dsi_send_dpi_spk_pkg_hs(sender, + MDFLD_DSI_DPI_SPK_SHUT_DOWN); + if (err) { + DRM_ERROR("Failed to send turn off packet\n"); + return err; + } + + /* FIXME disable CABC later*/ + + /*set display off*/ + mdfld_dsi_send_mcs_long_hs(sender, h8c7_set_display_off, 1, 0); + wait_timeout = jiffies + (HZ / 100); + while (time_before_eq(jiffies, wait_timeout)) + cpu_relax(); + + /* sleep in and wait for 150ms. */ + mdfld_dsi_send_mcs_long_hs(sender, h8c7_enter_sleep_mode, 1, 0); + wait_timeout = jiffies + (3 * HZ / 20); + while (time_before_eq(jiffies, wait_timeout)) + cpu_relax(); + + return 0; +} + +int mdfld_dsi_h8c7_set_brightness(struct mdfld_dsi_config *dsi_config, + int level) +{ + struct mdfld_dsi_pkg_sender *sender = + mdfld_dsi_get_pkg_sender(dsi_config); + int duty_val = 0; + static int cabc_enable = 1; + unsigned long wait_timeout; + + PSB_DEBUG_P2("Set brightness level %d...\n", level); + + if (!sender) { + DRM_ERROR("Failed to get DSI packet sender\n"); + return -EINVAL; + } + + duty_val = (255 * level) / 100; + h8c7_set_brightness[0] = (0x00000051 | (duty_val << 8)); + + /* set backlight to full brightness and wait for 10ms. */ + mdfld_dsi_send_mcs_long_hs(sender, h8c7_set_brightness, 1, 0); + wait_timeout = jiffies + (HZ / 100); + while (time_before_eq(jiffies, wait_timeout)) + cpu_relax(); + + return 0; +} + +int mdfld_dsi_h8c7_panel_reset(struct mdfld_dsi_config *dsi_config, + int reset_from) +{ + struct mdfld_dsi_hw_registers *regs; + struct mdfld_dsi_hw_context *ctx; + struct drm_device *dev; + int ret = 0; + static bool b_gpio_required[PSB_NUM_PIPE] = {0}; + unsigned gpio_mipi_panel_reset = 128; + + regs = &dsi_config->regs; + ctx = &dsi_config->dsi_hw_context; + dev = dsi_config->dev; + + if (IS_CTP(dev)) + gpio_mipi_panel_reset = 103; + + if (reset_from == RESET_FROM_BOOT_UP) { + b_gpio_required[dsi_config->pipe] = false; + if (dsi_config->pipe) { + PSB_DEBUG_ENTRY( + "GPIO reset for MIPIC is skipped!\n"); + goto fun_exit; + } + ret = gpio_request(gpio_mipi_panel_reset, "gfx"); + if (ret) { + DRM_ERROR( + "Failed to request gpio %d\n", gpio_mipi_panel_reset); + goto err; + } + b_gpio_required[dsi_config->pipe] = true; + + /* for get date from panel side is not easy, + so here use display side setting to judge + wheather panel have enabled or not by FW */ + if ((REG_READ(regs->dpll_reg) & BIT31) && + (REG_READ(regs->pipeconf_reg) & BIT30) && + (REG_READ(regs->mipi_reg) & BIT31)) { + PSB_DEBUG_ENTRY( + "FW has initialized the panel, skip reset during boot up\n."); + psb_enable_vblank(dev, dsi_config->pipe); + goto fun_exit; + } + } + if (b_gpio_required[dsi_config->pipe]) { + gpio_direction_output(gpio_mipi_panel_reset, 0); + gpio_set_value_cansleep(gpio_mipi_panel_reset, 0); + + /*reset low level width 11ms*/ + mdelay(10); + + gpio_direction_output(gpio_mipi_panel_reset, 1); + gpio_set_value_cansleep(gpio_mipi_panel_reset, 1); + + /*reset time 5ms*/ + mdelay(5); + } else { + PSB_DEBUG_ENTRY("pr2 panel reset fail.!"); + } +fun_exit: + if (b_gpio_required[dsi_config->pipe]) + PSB_DEBUG_ENTRY("pr2 panel reset successfull."); + return 0; +err: + gpio_free(gpio_mipi_panel_reset); + PSB_DEBUG_ENTRY("pr2 panel reset fail.!"); + return 0; +} + +struct drm_display_mode *h8c7_get_config_mode(struct drm_device *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; /*Disable GCT for now*/ + + 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 { + mode->hdisplay = 720; + mode->vdisplay = 1280; + mode->hsync_start = 816; + mode->hsync_end = 824; + mode->htotal = 920; + mode->vsync_start = 1284; + mode->vsync_end = 1286; + mode->vtotal = 1300; + mode->clock = 16500; /* calculated value is 71760; */ + } + + drm_mode_set_name(mode); + drm_mode_set_crtcinfo(mode, 0); + + mode->type |= DRM_MODE_TYPE_PREFERRED; + + return mode; +} + +int h8c7_get_panel_info(struct drm_device *dev, + int pipe, + struct panel_info *pi) +{ + if (!dev || !pi) + return -EINVAL; + + pi->width_mm = PANEL_4DOT3_WIDTH; + pi->height_mm = PANEL_4DOT3_HEIGHT; + + return 0; +} + +/*PR2 panel DPI encoder helper funcs*/ +static const +struct drm_encoder_helper_funcs mdfld_h8c7_dpi_encoder_helper_funcs = { + .save = mdfld_dsi_dpi_save, + .restore = mdfld_dsi_dpi_restore, + .dpms = mdfld_dsi_dpi_dpms, + .mode_fixup = mdfld_dsi_mode_fixup, + .prepare = mdfld_dsi_dpi_prepare, + .mode_set = mdfld_dsi_dpi_mode_set, + .commit = mdfld_dsi_dpi_commit, +}; + +/*PR2 panel DPI encoder funcs*/ +static const struct drm_encoder_funcs mdfld_h8c7_dpi_encoder_funcs = { + .destroy = drm_encoder_cleanup, +}; + +void h8c7_vid_init(struct drm_device *dev, struct panel_funcs *p_funcs) +{ + if (!dev || !p_funcs) { + DRM_ERROR("Invalid parameters\n"); + return; + } + + PSB_DEBUG_ENTRY("\n"); + + p_funcs->encoder_funcs = &mdfld_h8c7_dpi_encoder_funcs; + p_funcs->encoder_helper_funcs = &mdfld_h8c7_dpi_encoder_helper_funcs; + p_funcs->get_config_mode = &h8c7_get_config_mode; + p_funcs->update_fb = NULL; + p_funcs->get_panel_info = h8c7_get_panel_info; + p_funcs->reset = mdfld_dsi_h8c7_panel_reset; + p_funcs->drv_ic_init = mdfld_h8c7_dpi_ic_init; + p_funcs->dsi_controller_init = mdfld_h8c7_dpi_controller_init; + p_funcs->detect = mdfld_dsi_h8c7_detect; + p_funcs->get_panel_power_state = mdfld_h8c7_get_power_state; + p_funcs->power_on = mdfld_dsi_h8c7_power_on; + p_funcs->power_off = mdfld_dsi_h8c7_power_off; + p_funcs->set_brightness = mdfld_dsi_h8c7_set_brightness; +} diff --git a/drivers/staging/mrst/drv/mdfld_dsi_dbi.c b/drivers/staging/mrst/drv/mdfld_dsi_dbi.c index 67ef31d..fb25dce 100755 --- a/drivers/staging/mrst/drv/mdfld_dsi_dbi.c +++ b/drivers/staging/mrst/drv/mdfld_dsi_dbi.c @@ -34,6 +34,7 @@ #include #endif +#if 0 int enable_gfx_rtpm = 0; int enter_dsr = 0; @@ -61,6 +62,7 @@ void psb_runtimepm_wq_handler(struct work_struct *work) } } #endif +#endif /** @@ -308,7 +310,7 @@ void mdfld_dsi_dbi_enter_dsr (struct mdfld_dsi_dbi_output * dbi_output, int pipe if(!dbi_output) return; - gdbi_output = dbi_output; + //gdbi_output = dbi_output; if((dbi_output->mode_flags & MODE_SETTING_ON_GOING) || (psb_crtc && psb_crtc->mode_flags & MODE_SETTING_ON_GOING)) return; @@ -360,10 +362,12 @@ void mdfld_dsi_dbi_enter_dsr (struct mdfld_dsi_dbi_output * dbi_output, int pipe /*update mode state to IN_DSR*/ dbi_output->mode_flags |= MODE_SETTING_IN_DSR; +#if 0 if(pipe == 2){ enter_dsr = 1; //pm_schedule_suspend(&dev->pdev->dev, gfxrtdelay); } +#endif } #ifndef CONFIG_MDFLD_DSI_DPU @@ -476,12 +480,14 @@ void mdfld_dsi_dbi_exit_dsr (struct drm_device *dev, u32 update_src, void *p_sur dbi_output = dsr_info->dbi_outputs; +#if 0 #ifdef CONFIG_PM_RUNTIME if(drm_psb_ospm && !enable_gfx_rtpm) { // pm_runtime_allow(&gpDrmDevice->pdev->dev); // schedule_delayed_work(&rtpm_work, 120 * 1000); } #endif +#endif /*for each output, exit dsr*/ for(i=0; idbi_output_num; i++) { @@ -489,7 +495,7 @@ void mdfld_dsi_dbi_exit_dsr (struct drm_device *dev, u32 update_src, void *p_sur if (!dbi_output[i] || !dbi_output[i]->dbi_panel_on) continue; if(dbi_output[i]->mode_flags & MODE_SETTING_IN_DSR) { - enter_dsr = 0; + //enter_dsr = 0; mdfld_dbi_output_exit_dsr(dbi_output[i], dbi_output[i]->channel_num ? 2 : 0, p_surfaceAddr, check_hw_on_only); } } @@ -522,8 +528,8 @@ void mdfld_dbi_update_panel (struct drm_device *dev, int pipe) 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 enter_dsr = 0; + //int i; + //int enter_dsr = 0; u32 damage_mask = 0; dbi_outputs = dsr_info->dbi_outputs; @@ -557,6 +563,7 @@ void mdfld_dbi_update_panel (struct drm_device *dev, int pipe) dbi_output->dsr_idle_count++; } +#if 0 /*try to enter DSR*/ if (dbi_outputs[0]->dsr_idle_count > 1 && dbi_outputs[1]->dsr_idle_count > 1) { @@ -576,6 +583,7 @@ void mdfld_dbi_update_panel (struct drm_device *dev, int pipe) PSB_DEBUG_ENTRY("Runtime PM schedule suspend failed, rpm %d\n", dev_priv->rpm_enabled); #endif } +#endif } /*timers for DSR*/ @@ -906,3 +914,358 @@ out_err1: return NULL; } + +void mdfld_dsi_dbi_set_power(struct drm_encoder * encoder, bool on) +{ + int ret = 0; + struct mdfld_dsi_encoder * dsi_encoder = MDFLD_DSI_ENCODER(encoder); + struct mdfld_dsi_dbi_output * dbi_output = MDFLD_DSI_DBI_OUTPUT(dsi_encoder); + /*struct drm_device * dev = dbi_output->dev;*/ + struct drm_device* dev = encoder->dev; + struct drm_psb_private * dev_priv = dev->dev_private; + u32 reg_offset = 0; + int pipe = (dbi_output->channel_num == 0) ? 0 : 2; + + PSB_DEBUG_ENTRY("pipe %d : %s, panel on: %s\n",pipe, on ? "On" : "Off", dbi_output->dbi_panel_on ? "True" : "False"); + + if(pipe == 2) { + if(on) + dev_priv->dual_mipi = true; + else + dev_priv->dual_mipi = false; + reg_offset = MIPIC_REG_OFFSET; + } else { + if (!on) + dev_priv->dual_mipi = false; + } + + if (!ospm_power_using_hw_begin(OSPM_DISPLAY_ISLAND, OSPM_UHB_FORCE_POWER_ON)) { + DRM_ERROR("hw begin failed\n"); + return; + } + + if(on) { + if(dbi_output->dbi_panel_on) + goto out_err; + + ret = mdfld_dsi_dbi_update_power(dbi_output, DRM_MODE_DPMS_ON); + if(ret) { + DRM_ERROR("power on error\n"); + goto out_err; + } + + dbi_output->dbi_panel_on = true; + + if(pipe == 2) + dev_priv->dbi_panel_on2 = true; + else + dev_priv->dbi_panel_on = true; + + if (dev_priv->platform_rev_id != MDFLD_PNW_A0) + mdfld_enable_te(dev, pipe); + + } else { + if(!dbi_output->dbi_panel_on && !dbi_output->first_boot) + goto out_err; + + dbi_output->dbi_panel_on = false; + dbi_output->first_boot = false; + + if (pipe == 2) + dev_priv->dbi_panel_on2 = false; + else + dev_priv->dbi_panel_on = false; + + if (dev_priv->platform_rev_id != MDFLD_PNW_A0) + mdfld_disable_te(dev, pipe); + + ret = mdfld_dsi_dbi_update_power(dbi_output, DRM_MODE_DPMS_OFF); + if(ret) { + DRM_ERROR("power on error\n"); + goto out_err; + } + } + +out_err: + ospm_power_using_hw_end(OSPM_DISPLAY_ISLAND); + + if(ret) + DRM_ERROR("failed\n"); + else + PSB_DEBUG_ENTRY("successfully\n"); +} + + +void mdfld_dsi_dbi_mode_set(struct drm_encoder * encoder, + struct drm_display_mode * mode, + struct drm_display_mode * adjusted_mode) +{ + int ret = 0; + struct drm_device * dev = encoder->dev; + struct drm_psb_private * dev_priv = (struct drm_psb_private*)dev->dev_private; + struct mdfld_dsi_encoder * dsi_encoder = MDFLD_DSI_ENCODER(encoder); + struct mdfld_dsi_dbi_output * dsi_output = MDFLD_DSI_DBI_OUTPUT(dsi_encoder); + struct mdfld_dsi_config * dsi_config = mdfld_dsi_encoder_get_config(dsi_encoder); + struct mdfld_dsi_connector * dsi_connector = dsi_config->connector; + int pipe = dsi_connector->pipe; + u8 param = 0; + + /*regs*/ + u32 mipi_reg = MIPI; + u32 dspcntr_reg = DSPACNTR; + u32 pipeconf_reg = PIPEACONF; + u32 reg_offset = 0; + + /*values*/ + u32 dspcntr_val = dev_priv->dspcntr; + u32 pipeconf_val = dev_priv->pipeconf; + u32 h_active_area = mode->hdisplay; + u32 v_active_area = mode->vdisplay; + u32 mipi_val = (PASS_FROM_SPHY_TO_AFE | SEL_FLOPPED_HSTX); + + if (dev_priv->platform_rev_id != MDFLD_PNW_A0) + mipi_val = (PASS_FROM_SPHY_TO_AFE | SEL_FLOPPED_HSTX | TE_TRIGGER_GPIO_PIN); + + PSB_DEBUG_ENTRY("mipi_val =0x%x\n", mipi_val); + + PSB_DEBUG_ENTRY("type %s\n", (pipe == 2) ? "MIPI2" : "MIPI"); + PSB_DEBUG_ENTRY("h %d v %d\n", mode->hdisplay, mode->vdisplay); + + if(pipe == 2) { + mipi_reg = MIPI_C; + dspcntr_reg = DSPCCNTR; + pipeconf_reg = PIPECCONF; + + reg_offset = MIPIC_REG_OFFSET; + + dspcntr_val = dev_priv->dspcntr2; + pipeconf_val = dev_priv->pipeconf2; + } else { + mipi_val |= 0x2; /*two lanes for port A and C respectively*/ + } + + if (!ospm_power_using_hw_begin(OSPM_DISPLAY_ISLAND, OSPM_UHB_FORCE_POWER_ON)) { + DRM_ERROR("hw begin failed\n"); + return; + } + + REG_WRITE(dspcntr_reg, dspcntr_val); + REG_READ(dspcntr_reg); + + /*20ms delay before sending exit_sleep_mode*/ + msleep(20); + + /*send exit_sleep_mode DCS*/ + ret = mdfld_dsi_dbi_send_dcs(dsi_output, exit_sleep_mode, NULL, 0, CMD_DATA_SRC_SYSTEM_MEM); + if(ret) { + DRM_ERROR("sent exit_sleep_mode faild\n"); + goto out_err; + } + + if (dev_priv->platform_rev_id != MDFLD_PNW_A0) { + /*send set_tear_on DCS*/ + ret = mdfld_dsi_dbi_send_dcs(dsi_output, set_tear_on, ¶m, 1, CMD_DATA_SRC_SYSTEM_MEM); + + if(ret) { + DRM_ERROR("%s - sent set_tear_on faild\n", __func__); + goto out_err; + } + } + + REG_WRITE(pipeconf_reg, pipeconf_val | PIPEACONF_DSR); + REG_READ(pipeconf_reg); + + /*TODO: this looks ugly, try to move it to CRTC mode setting*/ + if(pipe == 2) { + dev_priv->pipeconf2 |= PIPEACONF_DSR; + } else { + dev_priv->pipeconf |= PIPEACONF_DSR; + } + + PSB_DEBUG_ENTRY("pipeconf %x\n", REG_READ(pipeconf_reg)); + + ret = mdfld_dsi_dbi_update_area(dsi_output, 0, 0, h_active_area - 1, v_active_area - 1); + if(ret) { + DRM_ERROR("update area failed\n"); + goto out_err; + } + +out_err: + ospm_power_using_hw_end(OSPM_DISPLAY_ISLAND); + + if(ret) { + DRM_ERROR("mode set failed\n"); + } else { + PSB_DEBUG_ENTRY("mode set done successfully\n"); + } +} + +void mdfld_dsi_dbi_prepare(struct drm_encoder * encoder) +{ + struct mdfld_dsi_encoder * dsi_encoder = MDFLD_DSI_ENCODER(encoder); + struct mdfld_dsi_dbi_output * dbi_output = MDFLD_DSI_DBI_OUTPUT(dsi_encoder); + + PSB_DEBUG_ENTRY("\n"); + + dbi_output->mode_flags |= MODE_SETTING_IN_ENCODER; + dbi_output->mode_flags &= ~MODE_SETTING_ENCODER_DONE; + + mdfld_dsi_dbi_set_power(encoder, false); +} + +void mdfld_dsi_dbi_commit(struct drm_encoder * encoder) +{ + struct mdfld_dsi_encoder * dsi_encoder = MDFLD_DSI_ENCODER(encoder); + struct mdfld_dsi_dbi_output * dbi_output = MDFLD_DSI_DBI_OUTPUT(dsi_encoder); + struct drm_device * dev = dbi_output->dev; + struct drm_psb_private * dev_priv = dev->dev_private; + +/*DSI DPU was still on debugging, will remove this option later*/ +#ifdef CONFIG_MDFLD_DSI_DPU + struct psb_drm_dpu_rect rect; +#endif + + PSB_DEBUG_ENTRY("\n"); + + mdfld_dsi_dbi_set_power(encoder, true); + + dbi_output->mode_flags &= ~MODE_SETTING_IN_ENCODER; + +#ifdef CONFIG_MDFLD_DSI_DPU + rect.x = rect.y = 0; + rect.width = 864; + rect.height = 480; +#endif + + if(dbi_output->channel_num == 1) { + dev_priv->dsr_fb_update |= MDFLD_DSR_2D_3D_2; +#ifdef CONFIG_MDFLD_DSI_DPU + /*if dpu enabled report a fullscreen damage*/ + mdfld_dbi_dpu_report_damage(dev, MDFLD_PLANEC, &rect); +#endif + } else { + dev_priv->dsr_fb_update |= MDFLD_DSR_2D_3D_0; + +#ifdef CONFIG_MDFLD_DSI_DPU + mdfld_dbi_dpu_report_damage(dev, MDFLD_PLANEA, &rect); + /*start dpu timer*/ + if (dev_priv->platform_rev_id == MDFLD_PNW_A0) + mdfld_dbi_dpu_timer_start(dev_priv->dbi_dpu_info); +#else + if (dev_priv->platform_rev_id == MDFLD_PNW_A0) + mdfld_dbi_dsr_timer_start(dev_priv->dbi_dsr_info); +#endif + } + + dbi_output->mode_flags |= MODE_SETTING_ENCODER_DONE; +} + +void mdfld_dsi_dbi_dpms(struct drm_encoder *encoder, int mode) +{ + struct mdfld_dsi_encoder * dsi_encoder = MDFLD_DSI_ENCODER(encoder); + struct mdfld_dsi_dbi_output * dbi_output = MDFLD_DSI_DBI_OUTPUT(dsi_encoder); +#if 0 + struct drm_device * dev = dbi_output->dev; + static bool bdispoff = false; +#endif + + PSB_DEBUG_ENTRY("%s \n", (mode == DRM_MODE_DPMS_ON ? "on":"off")); + + if (mode == DRM_MODE_DPMS_ON){ + /** + * FIXME: in case I am wrong! + * we don't need to exit dsr here to wake up plane/pipe/pll + * if everything goes right, hw_begin will resume them all + * during set_power. + */ + /* FIXME-RAJESH: TBR */ +#if 0 + if(bdispoff){ + mdfld_dsi_dbi_exit_dsr (dev, MDFLD_DSR_2D_3D, 0, 0); + } +#endif + mdfld_dsi_dbi_set_power(encoder, true); +#if 0 + if(gbgfxsuspended){ + gbgfxsuspended = false; + } + bdispoff = false; + gbdispstatus = true; +#endif + } else { + /** + * I am not sure whether this is the perfect place to + * turn rpm on since we still have a lot of CRTC turnning + * on work to do. + */ + mdfld_dsi_dbi_set_power(encoder, false); +#if 0 + bdispoff = true; + gbdispstatus = false; +#endif + } +} + + +/** + * Update the DBI MIPI Panel Frame Buffer. + */ +void mdfld_dsi_dbi_update_fb (struct mdfld_dsi_dbi_output * dbi_output, int pipe) +{ + struct mdfld_dsi_pkg_sender * sender = + mdfld_dsi_encoder_get_pkg_sender(&dbi_output->base); + struct drm_device * dev = dbi_output->dev; + 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 = MRST_DPLL_A; + u32 dspcntr_reg = DSPACNTR; + u32 pipeconf_reg = PIPEACONF; + u32 dsplinoff_reg = DSPALINOFF; + u32 dspsurf_reg = DSPASURF; + u32 reg_offset = 0; + + /*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) || + !(dbi_output->mode_flags & MODE_SETTING_ENCODER_DONE)) + return; + + if(pipe == 2) { + dspcntr_reg = DSPCCNTR; + pipeconf_reg = PIPECCONF; + dsplinoff_reg = DSPCLINOFF; + dspsurf_reg = DSPCSURF; + + reg_offset = MIPIC_REG_OFFSET; + } + + if (!ospm_power_using_hw_begin(OSPM_DISPLAY_ISLAND, OSPM_UHB_FORCE_POWER_ON)) { + DRM_ERROR("hw begin failed\n"); + return; + } + + /*check DBI FIFO status*/ + if (!(REG_READ(dpll_reg) & DPLL_VCO_ENABLE) || + !(REG_READ(dspcntr_reg) & DISPLAY_PLANE_ENABLE) || + !(REG_READ(pipeconf_reg) & DISPLAY_PLANE_ENABLE)) { + goto update_fb_out0; + } + + /*refresh plane changes*/ + REG_WRITE(dsplinoff_reg, REG_READ(dsplinoff_reg)); + REG_WRITE(dspsurf_reg, REG_READ(dspsurf_reg)); + REG_READ(dspsurf_reg); + + mdfld_dsi_send_dcs(sender, + write_mem_start, + NULL, + 0, + CMD_DATA_SRC_PIPE, + MDFLD_DSI_SEND_PACKAGE); + + dbi_output->dsr_fb_update_done = true; +update_fb_out0: + ospm_power_using_hw_end(OSPM_DISPLAY_ISLAND); +} + diff --git a/drivers/staging/mrst/drv/mdfld_dsi_dbi.h b/drivers/staging/mrst/drv/mdfld_dsi_dbi.h index f22903a..188e024 100644 --- a/drivers/staging/mrst/drv/mdfld_dsi_dbi.h +++ b/drivers/staging/mrst/drv/mdfld_dsi_dbi.h @@ -192,4 +192,10 @@ extern void mdfld_dbi_dsr_timer_start(struct mdfld_dbi_dsr_info * dsr_info); 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 void mdfld_dsi_dbi_update_fb (struct mdfld_dsi_dbi_output * dbi_output, int pipe); +extern void mdfld_dsi_dbi_dpms(struct drm_encoder *encoder, int mode); +extern void mdfld_dsi_dbi_commit(struct drm_encoder * encoder); +extern void mdfld_dsi_dbi_prepare(struct drm_encoder * encoder); +extern void mdfld_dsi_dbi_mode_set(struct drm_encoder * encoder, struct drm_display_mode * mode, struct drm_display_mode * adjusted_mode); +void mdfld_dsi_dbi_set_power(struct drm_encoder * encoder, bool on); #endif /*__MDFLD_DSI_DBI_H__*/ diff --git a/drivers/staging/mrst/drv/mdfld_dsi_dpi.c b/drivers/staging/mrst/drv/mdfld_dsi_dpi.c index 393df40..07fad67 100755 --- a/drivers/staging/mrst/drv/mdfld_dsi_dpi.c +++ b/drivers/staging/mrst/drv/mdfld_dsi_dpi.c @@ -1693,11 +1693,13 @@ void mdfld_dsi_dpi_dpms(struct drm_encoder *encoder, int mode) { PSB_DEBUG_ENTRY( "%s\n", (mode == DRM_MODE_DPMS_ON ? "on" : "off")); +#if 0 if (!gbdispstatus) { PSB_DEBUG_ENTRY( "panel in suspend status, skip turn on/off from DMPS"); return ; } +#endif if (mode == DRM_MODE_DPMS_ON) mdfld_dsi_dpi_set_power(encoder, true); @@ -1705,33 +1707,6 @@ void mdfld_dsi_dpi_dpms(struct drm_encoder *encoder, int mode) mdfld_dsi_dpi_set_power(encoder, false); } -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"); @@ -2337,23 +2312,17 @@ static int mipi_dsi_dev_ioctl(struct inode *inode, struct file *file, unsigned int cmd, unsigned long arg) { void __user *argp = (void __user*)arg; -#if defined(CONFIG_SUPPORT_TMD_MIPI_600X1024_DISPLAY) \ - || defined(CONFIG_SUPPORT_TOSHIBA_MIPI_DISPLAY) struct drm_encoder *encoder = gencoder; -#endif PSB_DEBUG_ENTRY("[DISPLAY] %s: MIPI DSI driver IOCTL, cmd = %d.\n", __func__, cmd); switch (cmd) { -#if defined(CONFIG_SUPPORT_TMD_MIPI_600X1024_DISPLAY) \ - || defined(CONFIG_SUPPORT_TOSHIBA_MIPI_DISPLAY) case IOCTL_LCM_POWER_ON: mdfld_dsi_dpi_set_power(encoder, 1); break; case IOCTL_LCM_POWER_OFF: mdfld_dsi_dpi_set_power(encoder, 0); break; -#endif default: printk(KERN_ERR "[DISPLAY] %s: MIPI DSI driver not support IOCTL.\n", __func__); break; diff --git a/drivers/staging/mrst/drv/mdfld_dsi_dpi.h b/drivers/staging/mrst/drv/mdfld_dsi_dpi.h index 02ce71c..b8e2dca 100755 --- a/drivers/staging/mrst/drv/mdfld_dsi_dpi.h +++ b/drivers/staging/mrst/drv/mdfld_dsi_dpi.h @@ -70,9 +70,6 @@ extern struct mdfld_dsi_encoder *mdfld_dsi_dpi_init(struct drm_device *dev, /*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, diff --git a/drivers/staging/mrst/drv/mdfld_dsi_output.c b/drivers/staging/mrst/drv/mdfld_dsi_output.c index 351f2ea..3c072c0 100755 --- a/drivers/staging/mrst/drv/mdfld_dsi_output.c +++ b/drivers/staging/mrst/drv/mdfld_dsi_output.c @@ -440,10 +440,10 @@ static enum drm_connector_status mdfld_dsi_connector_detect struct mdfld_dsi_connector *dsi_connector = MDFLD_DSI_CONNECTOR(psb_output); + PSB_DEBUG_ENTRY("\n"); #ifdef CONFIG_SUPPORT_TOSHIBA_MIPI_DISPLAY dsi_connector->status = connector_status_connected; #else - PSB_DEBUG_ENTRY("\n"); return dsi_connector->status; #endif } @@ -611,6 +611,8 @@ static void mdfld_dsi_connector_dpms(struct drm_connector *connector, int mode) struct drm_psb_private * dev_priv = dev->dev_private; bool panel_on, panel_on2; #endif + PSB_DEBUG_ENTRY("\n"); + /*first, execute dpms*/ drm_helper_connector_dpms(connector, mode); @@ -1068,13 +1070,8 @@ int mdfld_dsi_output_init(struct drm_device *dev, } if(pipe && dev_priv->dsi_configs[0]) { - dsi_config->dvr_ic_inited = 0; dev_priv->dsi_configs[1] = dsi_config; } else if(pipe == 0) { - if (get_panel_type(dev, pipe) == TMD_6X10_VID) - dsi_config->dvr_ic_inited = 0; - else - dsi_config->dvr_ic_inited = 1; dev_priv->dsi_configs[0] = dsi_config; } else { DRM_ERROR("Trying to init MIPI1 before MIPI0\n"); @@ -1176,3 +1173,31 @@ dsi_init_err0: return -EIO; } + +bool mdfld_dsi_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; +} + diff --git a/drivers/staging/mrst/drv/mdfld_dsi_output.h b/drivers/staging/mrst/drv/mdfld_dsi_output.h index d41caa9..08c5bdf 100755 --- a/drivers/staging/mrst/drv/mdfld_dsi_output.h +++ b/drivers/staging/mrst/drv/mdfld_dsi_output.h @@ -401,8 +401,6 @@ struct mdfld_dsi_config { int pipe; int changed; - int dvr_ic_inited; - int bpp; mdfld_dsi_encoder_t type; int lane_count; @@ -516,5 +514,7 @@ extern int mdfld_dsi_get_diagnostic_result(struct mdfld_dsi_config *dsi_config, u8 transmission); extern int mdfld_dsi_panel_reset(struct mdfld_dsi_config *dsi_config, int reset_from); - +extern bool mdfld_dsi_mode_fixup(struct drm_encoder *encoder, + struct drm_display_mode *mode, + struct drm_display_mode *adjusted_mode); #endif /*__MDFLD_DSI_OUTPUT_H__*/ diff --git a/drivers/staging/mrst/drv/mdfld_dsi_pkg_sender.c b/drivers/staging/mrst/drv/mdfld_dsi_pkg_sender.c index b61e220..a909aa7 100755 --- a/drivers/staging/mrst/drv/mdfld_dsi_pkg_sender.c +++ b/drivers/staging/mrst/drv/mdfld_dsi_pkg_sender.c @@ -118,7 +118,7 @@ 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); + PSB_DEBUG_DSI("Handling error 0x%08x\n", mask); switch(mask) { case BIT0: @@ -135,14 +135,14 @@ static int handle_dsi_error(struct mdfld_dsi_pkg_sender *sender, u32 mask) case BIT11: case BIT12: case BIT13: - PSB_DEBUG_ENTRY("No Action required\n"); + PSB_DEBUG_DSI("No Action required\n"); break; case BIT14: /*wait for all fifo empty*/ /*wait_for_all_fifos_empty(sender)*/; break; case BIT15: - PSB_DEBUG_ENTRY("No Action required\n"); + PSB_DEBUG_DSI("No Action required\n"); break; case BIT16: break; @@ -150,14 +150,14 @@ static int handle_dsi_error(struct mdfld_dsi_pkg_sender *sender, u32 mask) break; case BIT18: case BIT19: - PSB_DEBUG_ENTRY("High/Low contention detected\n"); + PSB_DEBUG_DSI("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 BIT20: - PSB_DEBUG_ENTRY("No Action required\n"); + PSB_DEBUG_DSI("No Action required\n"); break; case BIT21: /*wait for all fifo empty*/ @@ -170,24 +170,24 @@ static int handle_dsi_error(struct mdfld_dsi_pkg_sender *sender, u32 mask) case BIT25: case BIT26: case BIT27: - PSB_DEBUG_ENTRY("HS Gen fifo full\n"); + PSB_DEBUG_DSI("HS Gen fifo full\n"); REG_WRITE(intr_stat_reg, mask); wait_for_hs_fifos_empty(sender); break; case BIT28: - PSB_DEBUG_ENTRY("LP Gen fifo full\n"); + PSB_DEBUG_DSI("LP Gen fifo full\n"); REG_WRITE(intr_stat_reg, mask); wait_for_lp_fifos_empty(sender); break; case BIT29: case BIT30: case BIT31: - PSB_DEBUG_ENTRY("No Action required\n"); + PSB_DEBUG_DSI("No Action required\n"); break; } if(mask & REG_READ(intr_stat_reg)) { - PSB_DEBUG_ENTRY("Cannot clean interrupt 0x%08x\n", mask); + PSB_DEBUG_DSI("Cannot clean interrupt 0x%08x\n", mask); } return 0; @@ -207,7 +207,7 @@ static int dsi_error_handler(struct mdfld_dsi_pkg_sender * sender) for(i=0; i<32; i++) { mask = (0x00000001UL) << i; if(intr_stat & mask) { - PSB_DEBUG_ENTRY("[DSI]: %s\n", dsi_errors[i]); + PSB_DEBUG_DSI("[DSI]: %s\n", dsi_errors[i]); err = handle_dsi_error(sender, mask); if(err) DRM_ERROR("Cannot handle error\n"); @@ -260,7 +260,7 @@ static int send_dcs_pkg(struct mdfld_dsi_pkg_sender * sender, return -ENOTSUPP; } - PSB_DEBUG_ENTRY("Sending DCS pkg 0x%x...\n", dcs_pkg->cmd); + PSB_DEBUG_DSI("Sending DCS pkg 0x%x...\n", dcs_pkg->cmd); /*wait for DBI fifo empty*/ wait_for_dbi_fifo_empty(sender); @@ -284,7 +284,7 @@ static int send_dcs_pkg(struct mdfld_dsi_pkg_sender * sender, return -EAGAIN; } - PSB_DEBUG_ENTRY("sent DCS pkg 0x%x...\n", dcs_pkg->cmd); + PSB_DEBUG_DSI("sent DCS pkg 0x%x...\n", dcs_pkg->cmd); return 0; } @@ -354,7 +354,7 @@ static int __send_long_pkg(struct mdfld_dsi_pkg_sender * sender, wait_for_hs_fifos_empty(sender); for(i=0; ilen; i++) { - PSB_DEBUG_ENTRY("HS Sending data 0x%08x\n", *(dp + i)); + PSB_DEBUG_DSI("HS Sending data 0x%08x\n", *(dp + i)); REG_WRITE(hs_gen_data_reg, *(dp + i)); } @@ -365,7 +365,7 @@ static int __send_long_pkg(struct mdfld_dsi_pkg_sender * sender, wait_for_lp_fifos_empty(sender); for(i=0; ilen; i++) { - PSB_DEBUG_ENTRY("LP Sending data 0x%08x\n", *(dp + i)); + PSB_DEBUG_DSI("LP Sending data 0x%08x\n", *(dp + i)); REG_WRITE(lp_gen_data_reg, *(dp + i)); } @@ -383,7 +383,7 @@ static int __send_long_pkg(struct mdfld_dsi_pkg_sender * sender, static int send_mcs_short_pkg(struct mdfld_dsi_pkg_sender * sender, struct mdfld_dsi_pkg * pkg) { - PSB_DEBUG_ENTRY("Sending MCS short pkg...\n"); + PSB_DEBUG_DSI("Sending MCS short pkg...\n"); return __send_short_pkg(sender, pkg); } @@ -391,7 +391,7 @@ static int send_mcs_short_pkg(struct mdfld_dsi_pkg_sender * sender, static int send_mcs_long_pkg(struct mdfld_dsi_pkg_sender * sender, struct mdfld_dsi_pkg * pkg) { - PSB_DEBUG_ENTRY("Sending MCS long pkg...\n"); + PSB_DEBUG_DSI("Sending MCS long pkg...\n"); return __send_long_pkg(sender, pkg); } @@ -399,7 +399,7 @@ static int send_mcs_long_pkg(struct mdfld_dsi_pkg_sender * sender, static int send_gen_short_pkg(struct mdfld_dsi_pkg_sender * sender, struct mdfld_dsi_pkg * pkg) { - PSB_DEBUG_ENTRY("Sending GEN short pkg...\n"); + PSB_DEBUG_DSI("Sending GEN short pkg...\n"); return __send_short_pkg(sender, pkg); } @@ -407,7 +407,7 @@ static int send_gen_short_pkg(struct mdfld_dsi_pkg_sender * sender, static int send_gen_long_pkg(struct mdfld_dsi_pkg_sender * sender, struct mdfld_dsi_pkg * pkg) { - PSB_DEBUG_ENTRY("Sending GEN long pkg...\n"); + PSB_DEBUG_DSI("Sending GEN long pkg...\n"); return __send_long_pkg(sender, pkg); } @@ -454,7 +454,7 @@ static int send_pkg_prepare(struct mdfld_dsi_pkg_sender * sender, u8 cmd; u8 * data; - PSB_DEBUG_ENTRY("Prepare to Send type 0x%x pkg\n", pkg->pkg_type); + PSB_DEBUG_DSI("Prepare to Send type 0x%x pkg\n", pkg->pkg_type); switch(pkg->pkg_type) { case MDFLD_DSI_PKG_DCS: @@ -484,7 +484,7 @@ static int send_pkg_done(struct mdfld_dsi_pkg_sender * sender, u8 cmd; u8 * data; - PSB_DEBUG_ENTRY("Sent type 0x%x pkg\n", pkg->pkg_type); + PSB_DEBUG_DSI("Sent type 0x%x pkg\n", pkg->pkg_type); switch(pkg->pkg_type) { case MDFLD_DSI_PKG_DCS: @@ -519,7 +519,7 @@ static int do_send_pkg(struct mdfld_dsi_pkg_sender * sender, { int ret = 0; - PSB_DEBUG_ENTRY("Sending type 0x%x pkg\n", pkg->pkg_type); + PSB_DEBUG_DSI("Sending type 0x%x pkg\n", pkg->pkg_type); if(sender->status == MDFLD_DSI_PKG_SENDER_BUSY) { DRM_ERROR("sender is busy\n"); @@ -647,13 +647,13 @@ static int mdfld_dbi_cb_init(struct mdfld_dsi_pkg_sender * sender, struct psb_gt 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); + PSB_DEBUG_DSI("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"); + PSB_DEBUG_DSI("\n"); if(sender && sender->dbi_cb_addr) iounmap(sender->dbi_cb_addr); @@ -1019,7 +1019,7 @@ void dsi_controller_dbi_init(struct mdfld_dsi_config * dsi_config, int pipe) int lane_count = dsi_config->lane_count; u32 val = 0; - PSB_DEBUG_ENTRY("Init DBI interface on pipe %d...\n", pipe); + PSB_DEBUG_DSI("Init DBI interface on pipe %d...\n", pipe); /*un-ready device*/ REG_WRITE((MIPIA_DEVICE_READY_REG + reg_offset), 0x00000000); @@ -1071,7 +1071,7 @@ void dsi_controller_dpi_init(struct mdfld_dsi_config * dsi_config, int pipe) struct drm_display_mode * mode = dsi_config->mode; u32 val = 0; - PSB_DEBUG_ENTRY("Init DPI interface on pipe %d...\n", pipe); + PSB_DEBUG_DSI("Init DPI interface on pipe %d...\n", pipe); /*un-ready device*/ REG_WRITE((MIPIA_DEVICE_READY_REG + reg_offset), 0x00000000); @@ -1566,7 +1566,7 @@ int mdfld_dsi_pkg_sender_init(struct mdfld_dsi_connector * dsi_connector, int pi list_add_tail(&pkg->entry, &pkg_sender->free_list); } - PSB_DEBUG_ENTRY("initialized\n"); + PSB_DEBUG_DSI("initialized\n"); return 0; @@ -1610,5 +1610,5 @@ void mdfld_dsi_pkg_sender_destroy(struct mdfld_dsi_pkg_sender * sender) /*free*/ kfree(sender); - PSB_DEBUG_ENTRY("destroyed\n"); + PSB_DEBUG_DSI("destroyed\n"); } diff --git a/drivers/staging/mrst/drv/mdfld_output.c b/drivers/staging/mrst/drv/mdfld_output.c index 2f4ec81..cac2685 100644 --- a/drivers/staging/mrst/drv/mdfld_output.c +++ b/drivers/staging/mrst/drv/mdfld_output.c @@ -38,6 +38,8 @@ #include "displays/pyr_cmd.h" #include "displays/pyr_vid.h" #include "displays/tmd_6x10_vid.h" +#include "displays/h8c7_vid.h" +#include "displays/h8c7_cmd.h" #include "displays/hdmi.h" #include "psb_drv.h" @@ -58,11 +60,13 @@ int is_panel_vid_or_cmd(struct drm_device *dev) switch(dev_priv->panel_id) { case TMD_VID: case TMD_6X10_VID: + case H8C7_VID: case TPO_VID: case PYR_VID: ret = MDFLD_DSI_ENCODER_DPI; break; case TMD_CMD: + case H8C7_CMD: case TPO_CMD: case PYR_CMD: default: @@ -81,7 +85,6 @@ void mdfld_output_init(struct drm_device* dev) PSB_DEBUG_ENTRY( "[DISPLAY] %s: panel type is %d\n", __func__, p_type1); //DIV5-MM-DISPLAY-NC-LCM_INIT-00 init_panel(dev, 0, p_type1); - p_type2 = PYR_CMD; // Set the panel type as PYR_CMD by default #ifdef CONFIG_MDFD_DUAL_MIPI /* MIPI panel 2 */ p_type2 = get_panel_type(dev, 2); @@ -127,6 +130,20 @@ void init_panel(struct drm_device* dev, int mipi_pipe, enum panel_type p_type) NULL, p_vid_funcs); break; + case H8C7_CMD: + kfree(p_vid_funcs); + p_vid_funcs = NULL; + h8c7_cmd_init(dev, p_cmd_funcs); + ret = mdfld_dsi_output_init(dev, mipi_pipe, NULL, p_cmd_funcs, NULL); + case H8C7_VID: + kfree(p_cmd_funcs); + p_cmd_funcs = NULL; + h8c7_vid_init(dev, p_vid_funcs); + ret = mdfld_dsi_output_init(dev, mipi_pipe, + NULL, + NULL, + p_vid_funcs); + break; case TMD_CMD: /*tmd_cmd_init(dev, p_cmd_funcs);*/ kfree(p_vid_funcs); diff --git a/drivers/staging/mrst/drv/mdfld_output.h b/drivers/staging/mrst/drv/mdfld_output.h index d80e7db..37d2fb4 100644 --- a/drivers/staging/mrst/drv/mdfld_output.h +++ b/drivers/staging/mrst/drv/mdfld_output.h @@ -43,6 +43,8 @@ #define TMD_PANEL_HEIGHT 89 /* PR3 */ #define PYR_PANEL_WIDTH 53 #define PYR_PANEL_HEIGHT 95 +#define PANEL_4DOT3_WIDTH 53 +#define PANEL_4DOT3_HEIGHT 95 struct mdfld_dsi_config; diff --git a/drivers/staging/mrst/drv/psb_bl.c b/drivers/staging/mrst/drv/psb_bl.c index 8841a68..df8bd63 100755 --- a/drivers/staging/mrst/drv/psb_bl.c +++ b/drivers/staging/mrst/drv/psb_bl.c @@ -68,15 +68,14 @@ int psb_set_brightness(struct backlight_device *bd) else level = lastFailedBrightness; - DRM_DEBUG_DRIVER("backlight level set to %d\n", level); - PSB_DEBUG_ENTRY( "[DISPLAY] %s: level is %d\n", __func__, level); //DIV5-MM-DISPLAY-NC-LCM_INIT-00 + PSB_DEBUG_PM( "[DISPLAY] %s: level is %d\n", __func__, level); //DIV5-MM-DISPLAY-NC-LCM_INIT-00 /* Perform value bounds checking */ if (level < BRIGHTNESS_MIN_LEVEL) level = BRIGHTNESS_MIN_LEVEL; if(!gbdispstatus){ - PSB_DEBUG_ENTRY( "[DISPLAY]: already OFF ignoring brighness request \n"); + DRM_ERROR( "[DISPLAY]: already OFF ignoring brighness request \n"); //! there may exist concurrent racing, the gbdispstatus may haven't been set in gfx_late_resume yet. //! record here, and we may call brightness setting at the end of gfx_late_resume lastFailedBrightness = level; @@ -130,7 +129,7 @@ int psb_set_brightness(struct backlight_device *bd) if(!(dev_priv->dsr_fb_update & MDFLD_DSR_MIPI_CONTROL) && (dev_priv->dbi_panel_on || dev_priv->dbi_panel_on2)){ mdfld_dsi_dbi_exit_dsr(dev,MDFLD_DSR_MIPI_CONTROL, 0, 0); - PSB_DEBUG_ENTRY("Out of DSR before set brightness to %d.\n",adjusted_level); + PSB_DEBUG_PM("Out of DSR before set brightness to %d.\n",adjusted_level); } #endif @@ -147,7 +146,7 @@ int psb_set_brightness(struct backlight_device *bd) int psb_get_brightness(struct backlight_device *bd) { - DRM_DEBUG_DRIVER("brightness = 0x%x \n", psb_brightness); + PSB_DEBUG_PM("brightness = 0x%x \n", psb_brightness); /* return locally cached var instead of HW read (due to DPST etc.) */ return psb_brightness; diff --git a/drivers/staging/mrst/drv/psb_drv.c b/drivers/staging/mrst/drv/psb_drv.c index 120276a..ac88947 100755 --- a/drivers/staging/mrst/drv/psb_drv.c +++ b/drivers/staging/mrst/drv/psb_drv.c @@ -90,6 +90,7 @@ int drm_topaz_pmpolicy = PSB_PMPOLICY_NOPM; int drm_topaz_sbuswa; int drm_psb_ospm = 1; int drm_psb_gl3_enable = 1; +int drm_psb_dsr = 0; int drm_psb_topaz_clockgating = 0; int gfxrtdelay = 2 * 1000; int drm_psb_3D_vblank = 1; @@ -135,6 +136,7 @@ module_param_named(topaz_pmpolicy, drm_topaz_pmpolicy, int, 0600); module_param_named(topaz_sbuswa, drm_topaz_sbuswa, int, 0600); module_param_named(ospm, drm_psb_ospm, int, 0600); module_param_named(gl3_enabled, drm_psb_gl3_enable, int, 0600); +module_param_named(dsr, drm_psb_dsr, int, 0600); module_param_named(rtpm, gfxrtdelay, int, 0600); module_param_named(topaz_clockgating, drm_psb_topaz_clockgating, int, 0600); module_param_named(PanelID, PanelID, int, 0600); @@ -172,8 +174,21 @@ static int __init config_gl3(char *arg) return 0; } +static int __init config_dsr(char *arg) +{ + if (!arg) + return -EINVAL; + + if (!strcasecmp(arg, "0")) + drm_psb_dsr = 0; + else if (!strcasecmp(arg, "1")) + drm_psb_dsr = 1; + + return 0; +} early_param("ospm", config_ospm); early_param("gl3_enabled", config_gl3); +early_param("dsr", config_dsr); #endif static struct pci_device_id pciidlist[] = { @@ -2648,7 +2663,7 @@ static int psb_dpu_dsr_on_ioctl(struct drm_device *dev, void *arg, static int psb_dpu_dsr_off_ioctl(struct drm_device *dev, void *arg, struct drm_file *file_priv) { - static int pipe = 0; +// static int pipe = 0; #if defined(CONFIG_MDFLD_DSI_DPU) struct drm_psb_drv_dsr_off_arg *dsr_off_arg = (struct drm_psb_drv_dsr_off_arg *) arg; struct psb_drm_dpu_rect rect = dsr_off_arg->damage_rect; @@ -2658,12 +2673,13 @@ static int psb_dpu_dsr_off_ioctl(struct drm_device *dev, void *arg, struct drm_psb_private * dev_priv = (struct drm_psb_private *)dev->dev_private; - pipe++; +// pipe++; if ((dev_priv->dsr_fb_update & MDFLD_DSR_2D_3D) != MDFLD_DSR_2D_3D) { mdfld_dsi_dbi_exit_dsr(dev, MDFLD_DSR_2D_3D, 0, 0); } +#if 0 if (pipe > 0) { pipe = 0; if (gdbi_output && gbdispstatus == false) { @@ -2672,6 +2688,7 @@ static int psb_dpu_dsr_off_ioctl(struct drm_device *dev, void *arg, mdfld_dsi_dbi_enter_dsr(gdbi_output, 2); } } +#endif #endif return 0; @@ -3398,6 +3415,33 @@ static int psb_rtpm_write(struct file *file, const char *buffer, } return count; } +static int psb_dsr_read(char *buf, char **start, off_t offset, int request, + int *eof, void *data) +{ + if (drm_psb_dsr) + DRM_INFO("GFX DSR: enabled "); + else + DRM_INFO("GFX DSR: disabled "); + + return 0; +} + +static int psb_dsr_write(struct file *file, const char *buffer, + unsigned long count, void *data) +{ + char buf[2]; + if (count != sizeof(buf)) { + return -EINVAL; + } else { + if (copy_from_user(buf, buffer, count)) + return -EINVAL; + if (buf[count-1] != '\n') + return -EINVAL; + drm_psb_dsr = buf[0] - '0'; + } + + return 0; +} static int psb_ospm_read(char *buf, char **start, off_t offset, int request, int *eof, void *data) @@ -3677,19 +3721,23 @@ static int psb_proc_init(struct drm_minor *minor) struct proc_dir_entry *ent; struct proc_dir_entry *ent1; struct proc_dir_entry *rtpm; + struct proc_dir_entry *dsr; struct proc_dir_entry *ent_display_status; ent = create_proc_entry(OSPM_PROC_ENTRY, 0644, minor->proc_root); rtpm = create_proc_entry(RTPM_PROC_ENTRY, 0644, minor->proc_root); + dsr = create_proc_entry(DSR_PROC_ENTRY, 0644, minor->proc_root); ent_display_status = create_proc_entry(DISPLAY_PROC_ENTRY, 0644, minor->proc_root); ent1 = proc_create_data(BLC_PROC_ENTRY, 0, minor->proc_root, &psb_blc_proc_fops, minor); - if (!ent || !ent1 || !rtpm || !ent_display_status) + if (!ent || !ent1 || !rtpm || !ent_display_status || !dsr) return -1; ent->read_proc = psb_ospm_read; ent->write_proc = psb_ospm_write; ent->data = (void *)minor; rtpm->read_proc = psb_rtpm_read; rtpm->write_proc = psb_rtpm_write; + dsr->read_proc = psb_dsr_read; + dsr->write_proc = psb_dsr_write; ent_display_status->write_proc = psb_display_register_write; ent_display_status->read_proc = psb_display_register_read; ent_display_status->data = (void *)minor; @@ -3779,12 +3827,16 @@ static __init int parse_panelid(char *arg) PanelID = TPO_CMD; else if (!strcasecmp(arg, "PYR_CMD")) PanelID = PYR_CMD; + else if (!strcasecmp(arg, "H8C7_CMD")) + PanelID = H8C7_CMD; else if (!strcasecmp(arg, "TMD_VID")) PanelID = TMD_VID; else if (!strcasecmp(arg, "TPO_VID")) PanelID = TPO_VID; else if (!strcasecmp(arg, "PYR_VID")) PanelID = PYR_VID; + else if (!strcasecmp(arg, "H8C7_VID")) + PanelID = H8C7_VID; else PanelID = GCT_DETECT; diff --git a/drivers/staging/mrst/drv/psb_drv.h b/drivers/staging/mrst/drv/psb_drv.h index 2aca879..29dd85a 100755 --- a/drivers/staging/mrst/drv/psb_drv.h +++ b/drivers/staging/mrst/drv/psb_drv.h @@ -69,6 +69,8 @@ enum panel_type { TMD_CMD, TMD_VID, TMD_6X10_VID, + H8C7_CMD, + H8C7_VID, PYR_CMD, PYR_VID, TPO, @@ -93,6 +95,7 @@ enum panel_type { #define DRIVER_AUTHOR "Intel Corporation" #define OSPM_PROC_ENTRY "ospm" #define RTPM_PROC_ENTRY "rtpm" +#define DSR_PROC_ENTRY "dsr" #define BLC_PROC_ENTRY "mrst_blc" #define DISPLAY_PROC_ENTRY "display_status" @@ -1308,6 +1311,9 @@ struct backlight_device * psb_get_backlight_device(void); #define PSB_D_REG (1 << 8) #define PSB_D_MSVDX (1 << 9) #define PSB_D_TOPAZ (1 << 10) +/* debug DSI */ +#define PSB_D_DSI (1 << 16) +#define PSB_D_P2 (1 << 17) #ifndef DRM_DEBUG_CODE /* To enable debug printout, set drm_psb_debug in psb_drv.c @@ -1344,6 +1350,10 @@ extern int drm_topaz_sbuswa; PSB_DEBUG(PSB_D_MSVDX, _fmt, ##_arg) #define PSB_DEBUG_TOPAZ(_fmt, _arg...) \ PSB_DEBUG(PSB_D_TOPAZ, _fmt, ##_arg) +#define PSB_DEBUG_DSI(_fmt, _arg...) \ + PSB_DEBUG(PSB_D_DSI, _fmt, ##_arg) +#define PSB_DEBUG_P2(_fmt, _arg...) \ + PSB_DEBUG(PSB_D_P2, _fmt, ##_arg) #if DRM_DEBUG_CODE #define PSB_DEBUG(_flag, _fmt, _arg...) \ diff --git a/drivers/staging/mrst/drv/psb_intel_display2.c b/drivers/staging/mrst/drv/psb_intel_display2.c index dcaadd0..56c38f8 100755 --- a/drivers/staging/mrst/drv/psb_intel_display2.c +++ b/drivers/staging/mrst/drv/psb_intel_display2.c @@ -633,7 +633,8 @@ void mdfld_disable_crtc (struct drm_device *dev, int pipe) * support all MIPI panels later. */ if (pipe != 1 && ((get_panel_type(dev, pipe) == TMD_VID) || - (get_panel_type(dev, pipe) == TMD_6X10_VID))) + (get_panel_type(dev, pipe) == TMD_6X10_VID) || + (get_panel_type(dev, pipe) == H8C7_VID))) return; #endif @@ -739,7 +740,8 @@ static void mdfld_crtc_dpms(struct drm_crtc *crtc, int mode) * support all MIPI panels later. */ if (pipe != 1 && ((get_panel_type(dev, pipe) == TMD_VID) || - (get_panel_type(dev, pipe) == TMD_6X10_VID))) { + (get_panel_type(dev, pipe) == TMD_6X10_VID) || + (get_panel_type(dev, pipe) == H8C7_VID))) { return; } #endif @@ -748,13 +750,13 @@ static void mdfld_crtc_dpms(struct drm_crtc *crtc, int mode) OSPM_UHB_FORCE_POWER_ON)) return; +#if 0 /* Ignore if system is already in DSR and in suspended state. */ if(gbgfxsuspended && gbdispstatus == false && mode == 3){ if(dev_priv->rpm_enabled && pipe == 1){ // dev_priv->is_mipi_on = false; pm_request_idle(&gpDrmDevice->pdev->dev); } - ospm_power_using_hw_end(OSPM_DISPLAY_ISLAND); return; }else if(mode == 0) { @@ -762,6 +764,7 @@ static void mdfld_crtc_dpms(struct drm_crtc *crtc, int mode) //this will be set in encoder such as mdfld_dsi_dbi_dpms //gbdispstatus = true; } +#endif switch (pipe) { case 0: @@ -1433,7 +1436,8 @@ static int mdfld_crtc_mode_set(struct drm_crtc *crtc, * support all MIPI panels later. */ if (pipe != 1 && ((get_panel_type(dev, pipe) == TMD_VID) || - (get_panel_type(dev, pipe) == TMD_6X10_VID))) { + (get_panel_type(dev, pipe) == TMD_6X10_VID) || + (get_panel_type(dev, pipe) == H8C7_VID))) { if (pipe == 0) dsi_config = dev_priv->dsi_configs[0]; else if (pipe == 2) diff --git a/drivers/staging/mrst/drv/psb_powermgmt.c b/drivers/staging/mrst/drv/psb_powermgmt.c index d197486..3cf2e71 100755 --- a/drivers/staging/mrst/drv/psb_powermgmt.c +++ b/drivers/staging/mrst/drv/psb_powermgmt.c @@ -48,6 +48,7 @@ #undef OSPM_GFX_DPK #define SCU_CMD_VPROG2 0xe3 +extern int drm_psb_dsr; struct drm_device *gpDrmDevice = NULL; static struct mutex g_ospm_mutex; static bool gbSuspendInProgress = false; @@ -62,6 +63,16 @@ extern u32 DISP_PLANEB_STATUS; static bool gbSuspended = false; bool gbgfxsuspended = false; +static void psb_runtimepm_wq_handler(struct work_struct *work); +DECLARE_DELAYED_WORK(rtpm_work, psb_runtimepm_wq_handler); + +void psb_runtimepm_wq_handler(struct work_struct *work) +{ + struct drm_psb_private * dev_priv = gpDrmDevice->dev_private; + + if(gbdispstatus == false) + pm_runtime_allow(&gpDrmDevice->pdev->dev); +} /* * gfx_early_suspend * @@ -828,7 +839,8 @@ static int mdfld_save_display_registers (struct drm_device *dev, int pipe) */ #ifndef CONFIG_SUPPORT_TOSHIBA_MIPI_DISPLAY if (pipe != 1 && ((get_panel_type(dev, pipe) == TMD_VID) || - (get_panel_type(dev, pipe) == TMD_6X10_VID))) + (get_panel_type(dev, pipe) == TMD_6X10_VID) || + (get_panel_type(dev, pipe) == H8C7_VID))) return 0; #endif @@ -1016,6 +1028,8 @@ static int mdfld_restore_display_registers(struct drm_device *dev, int pipe) u32 dpll = 0; u32 timeout = 0; u32 reg_offset = 0; + u32 temp = 0; + u32 device_ready_reg = DEVICE_READY_REG; /* regester */ u32 dpll_reg = MRST_DPLL_A; @@ -1071,7 +1085,8 @@ static int mdfld_restore_display_registers(struct drm_device *dev, int pipe) */ #ifndef CONFIG_SUPPORT_TOSHIBA_MIPI_DISPLAY if (pipe != 1 && ((get_panel_type(dev, pipe) == TMD_VID) || - (get_panel_type(dev, pipe) == TMD_6X10_VID))) + (get_panel_type(dev, pipe) == TMD_6X10_VID) || + (get_panel_type(dev, pipe) == H8C7_VID))) return 0; #endif @@ -1254,9 +1269,6 @@ static int mdfld_restore_display_registers(struct drm_device *dev, int pipe) else msleep(20); - /*TODO: remove MIPI restore code later*/ - /*dsi_config->dvr_ic_inited = 0;*/ - /*mdfld_dsi_tmd_drv_ic_init(dsi_config, pipe);*/ } /*enable the plane*/ @@ -1267,29 +1279,28 @@ static int mdfld_restore_display_registers(struct drm_device *dev, int pipe) else msleep(20); -#if 0 /* revisit it later and check if we want to enter/exit from ULPS */ - /* LP Hold Release */ - temp = REG_READ(mipi_reg); - temp |= LP_OUTPUT_HOLD_RELEASE; - REG_WRITE(mipi_reg, temp); - mdelay(1); - + if ( drm_psb_dsr ) { + /* LP Hold Release */ + temp = REG_READ(mipi_reg); + temp |= LP_OUTPUT_HOLD_RELEASE; + REG_WRITE(mipi_reg, temp); + mdelay(1); - /* Set DSI host to exit from Utra Low Power State */ - temp = REG_READ(device_ready_reg); - temp &= ~ULPS_MASK; - temp |= 0x3; - temp |= EXIT_ULPS_DEV_READY; - REG_WRITE(device_ready_reg, temp); - mdelay(1); - temp = REG_READ(device_ready_reg); - temp &= ~ULPS_MASK; - temp |= EXITING_ULPS; - REG_WRITE(device_ready_reg, temp); - mdelay(1); -#endif + /* Set DSI host to exit from Utra Low Power State */ + temp = REG_READ(device_ready_reg); + temp &= ~ULPS_MASK; + temp |= 0x3; + temp |= EXIT_ULPS_DEV_READY; + REG_WRITE(device_ready_reg, temp); + mdelay(1); + temp = REG_READ(device_ready_reg); + temp &= ~ULPS_MASK; + temp |= EXITING_ULPS; + REG_WRITE(device_ready_reg, temp); + mdelay(1); + } /*enable the pipe*/ PSB_WVDC32(pipeconf_val, pipeconf_reg); @@ -1376,6 +1387,9 @@ void ospm_suspend_display(struct drm_device *dev) { struct drm_psb_private *dev_priv = dev->dev_private; int pp_stat, ret=0; + u32 temp = 0; + u32 device_ready_reg = DEVICE_READY_REG; + u32 mipi_reg = MIPI; #ifdef OSPM_GFX_DPK printk(KERN_ALERT "%s\n", __func__); @@ -1413,19 +1427,19 @@ void ospm_suspend_display(struct drm_device *dev) dev_priv->saveGL3_USE_WRT_INVAL = PSB_RVDC32(MDFLD_GL3_USE_WRT_INVAL); #endif -#if 0 /* revisit it later and check if we want to enter/exit from ULPS */ - /* Put the panel in ULPS mode for S0ix. */ - temp = REG_READ(device_ready_reg); - temp &= ~ULPS_MASK; - temp |= ENTERING_ULPS; - REG_WRITE(device_ready_reg, temp); + if ( drm_psb_dsr ) { + /* Put the panel in ULPS mode for S0ix. */ + temp = REG_READ(device_ready_reg); + temp &= ~ULPS_MASK; + temp |= ENTERING_ULPS; + REG_WRITE(device_ready_reg, temp); - /* LP Hold */ - temp = REG_READ(mipi_reg); - temp &= ~LP_OUTPUT_HOLD; - REG_WRITE(mipi_reg, temp); - mdelay(1); -#endif + /* LP Hold */ + temp = REG_READ(mipi_reg); + temp &= ~LP_OUTPUT_HOLD; + REG_WRITE(mipi_reg, temp); + mdelay(1); + } } else { save_display_registers(dev); @@ -1471,6 +1485,10 @@ void ospm_suspend_display(struct drm_device *dev) } ospm_power_island_down(OSPM_DISPLAY_ISLAND); + if ( drm_psb_dsr ) { + gbdispstatus = false; + schedule_delayed_work(&rtpm_work, 0); + } } /* @@ -1488,6 +1506,10 @@ void ospm_resume_display(struct pci_dev *pdev) char *uevent_string = NULL; #endif + if ( drm_psb_dsr ) { + gbdispstatus = true; + pm_runtime_forbid(&gpDrmDevice->pdev->dev); + } #ifdef OSPM_GFX_DPK printk(KERN_ALERT "%s\n", __func__); #endif @@ -1680,12 +1702,16 @@ static void gfx_early_suspend(struct early_suspend *h) printk(KERN_ALERT "\n gfx_early_suspend\n"); #endif + if (gbSuspended) + return; + if( dev_priv->drm_psb_widi ) dev_priv->drm_psb_widi = 0; /*Display off*/ if (IS_MDFLD(gpDrmDevice)) { if ((dev_priv->panel_id == TMD_VID) || + (dev_priv->panel_id == H8C7_VID) || (dev_priv->panel_id == TMD_6X10_VID)) { #ifdef CONFIG_SUPPORT_TOSHIBA_MIPI_DISPLAY if (dev_priv->encoder0 && @@ -1707,7 +1733,8 @@ static void gfx_early_suspend(struct early_suspend *h) enc_funcs->save(encoder); } #endif - } else if (dev_priv->panel_id == TPO_CMD) { + } else if ((dev_priv->panel_id == TPO_CMD) || + (dev_priv->panel_id == H8C7_CMD)) { if (dev_priv->encoder0 && (dev_priv->panel_desc & DISPLAY_A)) mdfld_dsi_dbi_set_power( @@ -1726,7 +1753,7 @@ static void gfx_early_suspend(struct early_suspend *h) #ifdef OSPM_GFX_DPK printk(KERN_ALERT " allow GFX runtime_pm\n"); #endif - pm_runtime_allow(&gpDrmDevice->pdev->dev); + schedule_delayed_work(&rtpm_work, 0); #endif } @@ -1742,6 +1769,9 @@ static void gfx_late_resume(struct early_suspend *h) printk(KERN_ALERT "\ngfx_late_resume\n"); #endif + if (!gbSuspended) + return; + if( dev_priv->drm_psb_widi ) dev_priv->drm_psb_widi = 0; @@ -1757,6 +1787,7 @@ static void gfx_late_resume(struct early_suspend *h) #endif if (IS_MDFLD(gpDrmDevice)) { if ((dev_priv->panel_id == TMD_VID) || + (dev_priv->panel_id == H8C7_VID) || (dev_priv->panel_id == TMD_6X10_VID)) { #ifdef CONFIG_SUPPORT_TOSHIBA_MIPI_DISPLAY if (dev_priv->encoder0 && @@ -1776,9 +1807,10 @@ static void gfx_late_resume(struct early_suspend *h) continue; if (enc_funcs && enc_funcs->restore) enc_funcs->restore(encoder); - } + } #endif - } else if (dev_priv->panel_id == TPO_CMD) { + } else if ((dev_priv->panel_id == TPO_CMD) || + (dev_priv->panel_id == H8C7_CMD)) { if (dev_priv->encoder0 && (dev_priv->panel_desc & DISPLAY_A)) mdfld_dsi_dbi_set_power( diff --git a/drivers/staging/mrst/drv/pyr_cmd.c b/drivers/staging/mrst/drv/pyr_cmd.c index eff7adb..9cf34d6 100644 --- a/drivers/staging/mrst/drv/pyr_cmd.c +++ b/drivers/staging/mrst/drv/pyr_cmd.c @@ -427,17 +427,21 @@ static void pyr_dsi_dbi_dpms(struct drm_encoder *encoder, int mode) PSB_DEBUG_ENTRY("%s \n", (mode == DRM_MODE_DPMS_ON ? "on":"off")); if (mode == DRM_MODE_DPMS_ON){ +#if 0 if(gbgfxsuspended && bdispoff){ bdispoff = false; gbdispstatus = true; gbgfxsuspended = false; mdfld_dsi_dbi_exit_dsr (dev, MDFLD_DSR_2D_3D, 0, 0); } +#endif pyr_dsi_dbi_set_power(encoder, true); } else { +#if 0 bdispoff = true; gbdispstatus = false; +#endif pyr_dsi_dbi_set_power(encoder, false); } } diff --git a/drivers/staging/mrst/drv/tmd_6x10_vid.c b/drivers/staging/mrst/drv/tmd_6x10_vid.c index 5978a40..360d6fe 100755 --- a/drivers/staging/mrst/drv/tmd_6x10_vid.c +++ b/drivers/staging/mrst/drv/tmd_6x10_vid.c @@ -92,7 +92,7 @@ void mdfld_dsi_pr2_ic_init(struct mdfld_dsi_config *dsi_config, int pipe) return; } - printk(KERN_ALERT "[DISPLAY TRK] Enter %s\n", __func__); + PSB_DEBUG_ENTRY("\n"); /*wait for 5ms*/ wait_timeout = jiffies + (HZ / 200); @@ -371,7 +371,7 @@ static int mdfld_dsi_pr2_set_brightness(struct mdfld_dsi_config *dsi_config, mdfld_dsi_get_pkg_sender(dsi_config); int duty_val = 0; - PSB_DEBUG_ENTRY("Set brightness level %d...\n", level); + PSB_DEBUG_P2("Set brightness level %d...\n", level); if (!sender) { DRM_ERROR("Failed to get DSI packet sender\n"); @@ -569,7 +569,7 @@ struct drm_encoder_helper_funcs mdfld_pr2_dpi_encoder_helper_funcs = { .save = mdfld_dsi_dpi_save, .restore = mdfld_dsi_dpi_restore, .dpms = mdfld_dsi_dpi_dpms, - .mode_fixup = mdfld_dsi_dpi_mode_fixup, + .mode_fixup = mdfld_dsi_mode_fixup, .prepare = mdfld_dsi_dpi_prepare, .mode_set = mdfld_dsi_dpi_mode_set, .commit = mdfld_dsi_dpi_commit, diff --git a/drivers/staging/mrst/drv/tmd_vid.c b/drivers/staging/mrst/drv/tmd_vid.c index a0580ee..9f261eb 100644 --- a/drivers/staging/mrst/drv/tmd_vid.c +++ b/drivers/staging/mrst/drv/tmd_vid.c @@ -500,7 +500,7 @@ struct drm_encoder_helper_funcs mdfld_tmd_dpi_encoder_helper_funcs = { .save = mdfld_dsi_dpi_save, .restore = mdfld_dsi_dpi_restore, .dpms = mdfld_dsi_dpi_dpms, - .mode_fixup = mdfld_dsi_dpi_mode_fixup, + .mode_fixup = mdfld_dsi_mode_fixup, .prepare = mdfld_dsi_dpi_prepare, .mode_set = mdfld_dsi_dpi_mode_set, .commit = mdfld_dsi_dpi_commit, diff --git a/drivers/staging/mrst/drv/tpo_cmd.c b/drivers/staging/mrst/drv/tpo_cmd.c index 86d3d63..d345fb6 100755 --- a/drivers/staging/mrst/drv/tpo_cmd.c +++ b/drivers/staging/mrst/drv/tpo_cmd.c @@ -99,384 +99,6 @@ tpo_cmd_get_config_mode(struct drm_device* dev) return mode; } -static bool mdfld_dsi_dbi_mode_fixup(struct drm_encoder * encoder, - struct drm_display_mode * mode, - struct drm_display_mode * adjusted_mode) -{ - struct drm_device* dev = encoder->dev; - struct drm_display_mode * fixed_mode = tpo_cmd_get_config_mode(dev); - - 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); - kfree(fixed_mode); - } - - return true; -} - -void mdfld_dsi_dbi_set_power(struct drm_encoder * encoder, bool on) -{ - int ret = 0; - struct mdfld_dsi_encoder * dsi_encoder = MDFLD_DSI_ENCODER(encoder); - struct mdfld_dsi_dbi_output * dbi_output = MDFLD_DSI_DBI_OUTPUT(dsi_encoder); - /*struct drm_device * dev = dbi_output->dev;*/ - struct drm_device* dev = encoder->dev; - struct drm_psb_private * dev_priv = dev->dev_private; - u32 reg_offset = 0; - int pipe = (dbi_output->channel_num == 0) ? 0 : 2; - - PSB_DEBUG_ENTRY("pipe %d : %s, panel on: %s\n",pipe, on ? "On" : "Off", dbi_output->dbi_panel_on ? "True" : "False"); - - if(pipe == 2) { - if(on) - dev_priv->dual_mipi = true; - else - dev_priv->dual_mipi = false; - reg_offset = MIPIC_REG_OFFSET; - } else { - if (!on) - dev_priv->dual_mipi = false; - } - - if (!ospm_power_using_hw_begin(OSPM_DISPLAY_ISLAND, OSPM_UHB_FORCE_POWER_ON)) { - DRM_ERROR("hw begin failed\n"); - return; - } - - if(on) { - if(dbi_output->dbi_panel_on) - goto out_err; - - ret = mdfld_dsi_dbi_update_power(dbi_output, DRM_MODE_DPMS_ON); - if(ret) { - DRM_ERROR("power on error\n"); - goto out_err; - } - - dbi_output->dbi_panel_on = true; - - if(pipe == 2) - dev_priv->dbi_panel_on2 = true; - else - dev_priv->dbi_panel_on = true; - - if (dev_priv->platform_rev_id != MDFLD_PNW_A0) - mdfld_enable_te(dev, pipe); - - } else { - if(!dbi_output->dbi_panel_on && !dbi_output->first_boot) - goto out_err; - - dbi_output->dbi_panel_on = false; - dbi_output->first_boot = false; - - if (pipe == 2) - dev_priv->dbi_panel_on2 = false; - else - dev_priv->dbi_panel_on = false; - - if (dev_priv->platform_rev_id != MDFLD_PNW_A0) - mdfld_disable_te(dev, pipe); - - ret = mdfld_dsi_dbi_update_power(dbi_output, DRM_MODE_DPMS_OFF); - if(ret) { - DRM_ERROR("power on error\n"); - goto out_err; - } - } - -out_err: - ospm_power_using_hw_end(OSPM_DISPLAY_ISLAND); - - if(ret) - DRM_ERROR("failed\n"); - else - PSB_DEBUG_ENTRY("successfully\n"); -} - - -static void mdfld_dsi_dbi_mode_set(struct drm_encoder * encoder, - struct drm_display_mode * mode, - struct drm_display_mode * adjusted_mode) -{ - int ret = 0; - struct drm_device * dev = encoder->dev; - struct drm_psb_private * dev_priv = (struct drm_psb_private*)dev->dev_private; - struct mdfld_dsi_encoder * dsi_encoder = MDFLD_DSI_ENCODER(encoder); - struct mdfld_dsi_dbi_output * dsi_output = MDFLD_DSI_DBI_OUTPUT(dsi_encoder); - struct mdfld_dsi_config * dsi_config = mdfld_dsi_encoder_get_config(dsi_encoder); - struct mdfld_dsi_connector * dsi_connector = dsi_config->connector; - int pipe = dsi_connector->pipe; - u8 param = 0; - - /*regs*/ - u32 mipi_reg = MIPI; - u32 dspcntr_reg = DSPACNTR; - u32 pipeconf_reg = PIPEACONF; - u32 reg_offset = 0; - - /*values*/ - u32 dspcntr_val = dev_priv->dspcntr; - u32 pipeconf_val = dev_priv->pipeconf; - u32 h_active_area = mode->hdisplay; - u32 v_active_area = mode->vdisplay; - u32 mipi_val = (PASS_FROM_SPHY_TO_AFE | SEL_FLOPPED_HSTX); - - if (dev_priv->platform_rev_id != MDFLD_PNW_A0) - mipi_val = (PASS_FROM_SPHY_TO_AFE | SEL_FLOPPED_HSTX | TE_TRIGGER_GPIO_PIN); - - PSB_DEBUG_ENTRY("mipi_val =0x%x\n", mipi_val); - - PSB_DEBUG_ENTRY("type %s\n", (pipe == 2) ? "MIPI2" : "MIPI"); - PSB_DEBUG_ENTRY("h %d v %d\n", mode->hdisplay, mode->vdisplay); - - if(pipe == 2) { - mipi_reg = MIPI_C; - dspcntr_reg = DSPCCNTR; - pipeconf_reg = PIPECCONF; - - reg_offset = MIPIC_REG_OFFSET; - - dspcntr_val = dev_priv->dspcntr2; - pipeconf_val = dev_priv->pipeconf2; - } else { - mipi_val |= 0x2; /*two lanes for port A and C respectively*/ - } - - if (!ospm_power_using_hw_begin(OSPM_DISPLAY_ISLAND, OSPM_UHB_FORCE_POWER_ON)) { - DRM_ERROR("hw begin failed\n"); - return; - } - - REG_WRITE(dspcntr_reg, dspcntr_val); - REG_READ(dspcntr_reg); - - /*20ms delay before sending exit_sleep_mode*/ - msleep(20); - - /*send exit_sleep_mode DCS*/ - ret = mdfld_dsi_dbi_send_dcs(dsi_output, exit_sleep_mode, NULL, 0, CMD_DATA_SRC_SYSTEM_MEM); - if(ret) { - DRM_ERROR("sent exit_sleep_mode faild\n"); - goto out_err; - } - - if (dev_priv->platform_rev_id != MDFLD_PNW_A0) { - /*send set_tear_on DCS*/ - ret = mdfld_dsi_dbi_send_dcs(dsi_output, set_tear_on, ¶m, 1, CMD_DATA_SRC_SYSTEM_MEM); - - if(ret) { - DRM_ERROR("%s - sent set_tear_on faild\n", __func__); - goto out_err; - } - } - - REG_WRITE(pipeconf_reg, pipeconf_val | PIPEACONF_DSR); - REG_READ(pipeconf_reg); - - /*TODO: this looks ugly, try to move it to CRTC mode setting*/ - if(pipe == 2) { - dev_priv->pipeconf2 |= PIPEACONF_DSR; - } else { - dev_priv->pipeconf |= PIPEACONF_DSR; - } - - PSB_DEBUG_ENTRY("pipeconf %x\n", REG_READ(pipeconf_reg)); - - ret = mdfld_dsi_dbi_update_area(dsi_output, 0, 0, h_active_area - 1, v_active_area - 1); - if(ret) { - DRM_ERROR("update area failed\n"); - goto out_err; - } - -out_err: - ospm_power_using_hw_end(OSPM_DISPLAY_ISLAND); - - if(ret) { - DRM_ERROR("mode set failed\n"); - } else { - PSB_DEBUG_ENTRY("mode set done successfully\n"); - } -} - -static void mdfld_dsi_dbi_prepare(struct drm_encoder * encoder) -{ - struct mdfld_dsi_encoder * dsi_encoder = MDFLD_DSI_ENCODER(encoder); - struct mdfld_dsi_dbi_output * dbi_output = MDFLD_DSI_DBI_OUTPUT(dsi_encoder); - - PSB_DEBUG_ENTRY("\n"); - - dbi_output->mode_flags |= MODE_SETTING_IN_ENCODER; - dbi_output->mode_flags &= ~MODE_SETTING_ENCODER_DONE; - - mdfld_dsi_dbi_set_power(encoder, false); -} - -static void mdfld_dsi_dbi_commit(struct drm_encoder * encoder) -{ - struct mdfld_dsi_encoder * dsi_encoder = MDFLD_DSI_ENCODER(encoder); - struct mdfld_dsi_dbi_output * dbi_output = MDFLD_DSI_DBI_OUTPUT(dsi_encoder); - struct drm_device * dev = dbi_output->dev; - struct drm_psb_private * dev_priv = dev->dev_private; - -/*DSI DPU was still on debugging, will remove this option later*/ -#ifdef CONFIG_MDFLD_DSI_DPU - struct psb_drm_dpu_rect rect; -#endif - - PSB_DEBUG_ENTRY("\n"); - - mdfld_dsi_dbi_set_power(encoder, true); - - dbi_output->mode_flags &= ~MODE_SETTING_IN_ENCODER; - -#ifdef CONFIG_MDFLD_DSI_DPU - rect.x = rect.y = 0; - rect.width = 864; - rect.height = 480; -#endif - - if(dbi_output->channel_num == 1) { - dev_priv->dsr_fb_update |= MDFLD_DSR_2D_3D_2; -#ifdef CONFIG_MDFLD_DSI_DPU - /*if dpu enabled report a fullscreen damage*/ - mdfld_dbi_dpu_report_damage(dev, MDFLD_PLANEC, &rect); -#endif - } else { - dev_priv->dsr_fb_update |= MDFLD_DSR_2D_3D_0; - -#ifdef CONFIG_MDFLD_DSI_DPU - mdfld_dbi_dpu_report_damage(dev, MDFLD_PLANEA, &rect); - /*start dpu timer*/ - if (dev_priv->platform_rev_id == MDFLD_PNW_A0) - mdfld_dbi_dpu_timer_start(dev_priv->dbi_dpu_info); -#else - if (dev_priv->platform_rev_id == MDFLD_PNW_A0) - mdfld_dbi_dsr_timer_start(dev_priv->dbi_dsr_info); -#endif - } - - dbi_output->mode_flags |= MODE_SETTING_ENCODER_DONE; -} - -static void mdfld_dsi_dbi_dpms(struct drm_encoder *encoder, int mode) -{ - struct mdfld_dsi_encoder * dsi_encoder = MDFLD_DSI_ENCODER(encoder); - struct mdfld_dsi_dbi_output * dbi_output = MDFLD_DSI_DBI_OUTPUT(dsi_encoder); - struct drm_device * dev = dbi_output->dev; - static bool bdispoff = false; - - PSB_DEBUG_ENTRY("%s \n", (mode == DRM_MODE_DPMS_ON ? "on":"off")); - - if (mode == DRM_MODE_DPMS_ON){ - /** - * FIXME: in case I am wrong! - * we don't need to exit dsr here to wake up plane/pipe/pll - * if everything goes right, hw_begin will resume them all - * during set_power. - */ - /* FIXME-RAJESH: TBR */ -#if 0 - if(bdispoff){ - mdfld_dsi_dbi_exit_dsr (dev, MDFLD_DSR_2D_3D, 0, 0); - } -#endif - mdfld_dsi_dbi_set_power(encoder, true); -#if 0 - if(gbgfxsuspended){ - gbgfxsuspended = false; - } - bdispoff = false; - gbdispstatus = true; -#endif - } else { - /** - * I am not sure whether this is the perfect place to - * turn rpm on since we still have a lot of CRTC turnning - * on work to do. - */ - mdfld_dsi_dbi_set_power(encoder, false); -#if 0 - bdispoff = true; - gbdispstatus = false; -#endif - } -} - - -/** - * Update the DBI MIPI Panel Frame Buffer. - */ -static void mdfld_dsi_dbi_update_fb (struct mdfld_dsi_dbi_output * dbi_output, int pipe) -{ - struct mdfld_dsi_pkg_sender * sender = - mdfld_dsi_encoder_get_pkg_sender(&dbi_output->base); - struct drm_device * dev = dbi_output->dev; - 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 = MRST_DPLL_A; - u32 dspcntr_reg = DSPACNTR; - u32 pipeconf_reg = PIPEACONF; - u32 dsplinoff_reg = DSPALINOFF; - u32 dspsurf_reg = DSPASURF; - u32 reg_offset = 0; - - /*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) || - !(dbi_output->mode_flags & MODE_SETTING_ENCODER_DONE)) - return; - - if(pipe == 2) { - dspcntr_reg = DSPCCNTR; - pipeconf_reg = PIPECCONF; - dsplinoff_reg = DSPCLINOFF; - dspsurf_reg = DSPCSURF; - - reg_offset = MIPIC_REG_OFFSET; - } - - if (!ospm_power_using_hw_begin(OSPM_DISPLAY_ISLAND, OSPM_UHB_FORCE_POWER_ON)) { - DRM_ERROR("hw begin failed\n"); - return; - } - - /*check DBI FIFO status*/ - if (!(REG_READ(dpll_reg) & DPLL_VCO_ENABLE) || - !(REG_READ(dspcntr_reg) & DISPLAY_PLANE_ENABLE) || - !(REG_READ(pipeconf_reg) & DISPLAY_PLANE_ENABLE)) { - goto update_fb_out0; - } - - /*refresh plane changes*/ - REG_WRITE(dsplinoff_reg, REG_READ(dsplinoff_reg)); - REG_WRITE(dspsurf_reg, REG_READ(dspsurf_reg)); - REG_READ(dspsurf_reg); - - mdfld_dsi_send_dcs(sender, - write_mem_start, - NULL, - 0, - CMD_DATA_SRC_PIPE, - MDFLD_DSI_SEND_PACKAGE); - - dbi_output->dsr_fb_update_done = true; -update_fb_out0: - ospm_power_using_hw_end(OSPM_DISPLAY_ISLAND); -} - static int tpo_cmd_get_panel_info(struct drm_device * dev, int pipe, struct panel_info * pi) @@ -542,7 +164,7 @@ static int mdfld_dsi_tpo_cmd_set_brightness(struct mdfld_dsi_config *dsi_config, /*TPO 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, + .mode_fixup = mdfld_dsi_mode_fixup, .prepare = mdfld_dsi_dbi_prepare, .mode_set = mdfld_dsi_dbi_mode_set, .commit = mdfld_dsi_dbi_commit, diff --git a/drivers/staging/mrst/drv/tpo_vid.c b/drivers/staging/mrst/drv/tpo_vid.c index e2da608..d1c0c24 100644 --- a/drivers/staging/mrst/drv/tpo_vid.c +++ b/drivers/staging/mrst/drv/tpo_vid.c @@ -151,7 +151,7 @@ static int mdfld_dsi_tpo_vid_set_brightness(struct mdfld_dsi_config *dsi_config, /*TPO DPI encoder helper funcs*/ static const struct drm_encoder_helper_funcs mdfld_tpo_dpi_encoder_helper_funcs = { .dpms = mdfld_dsi_dpi_dpms, - .mode_fixup = mdfld_dsi_dpi_mode_fixup, + .mode_fixup = mdfld_dsi_mode_fixup, .prepare = mdfld_dsi_dpi_prepare, .mode_set = mdfld_dsi_dpi_mode_set, .commit = mdfld_dsi_dpi_commit, diff --git a/drivers/staging/mrst/medfield/Makefile b/drivers/staging/mrst/medfield/Makefile index 5dfd9fe..a564f4b 100644 --- a/drivers/staging/mrst/medfield/Makefile +++ b/drivers/staging/mrst/medfield/Makefile @@ -194,6 +194,8 @@ gfx-y += $(DRMDRVDIR)/psb_bl.o \ $(DRMDRVDIR)/tpo_vid.o \ $(DRMDRVDIR)/tmd_vid.o \ $(DRMDRVDIR)/tmd_6x10_vid.o \ + $(DRMDRVDIR)/h8c7_vid.o \ + $(DRMDRVDIR)/h8c7_cmd.o \ $(DRMDRVDIR)/pyr_cmd.o \ $(DRMDRVDIR)/mdfld_dsi_pkg_sender.o \ $(DRMDRVDIR)/psb_powermgmt.o \ diff --git a/drivers/staging/mrst/pvr/services4/3rdparty/linux_framebuffer_drm/drmlfb_displayclass.c b/drivers/staging/mrst/pvr/services4/3rdparty/linux_framebuffer_drm/drmlfb_displayclass.c index f6095c9..97987dd 100755 --- a/drivers/staging/mrst/pvr/services4/3rdparty/linux_framebuffer_drm/drmlfb_displayclass.c +++ b/drivers/staging/mrst/pvr/services4/3rdparty/linux_framebuffer_drm/drmlfb_displayclass.c @@ -44,7 +44,28 @@ #if !defined(SUPPORT_DRI_DRM) #error "SUPPORT_DRI_DRM must be set" #endif +/* + DSR +*/ +extern int drm_psb_dsr; +extern struct drm_device *gpDrmDevice; +extern void ospm_suspend_display(struct drm_device *dev); +extern void ospm_resume_display(struct pci_dev *pdev); + +static void dsr_wq_handler(struct work_struct *work); +DECLARE_DELAYED_WORK(dsr_work, dsr_wq_handler); + +void dsr_wq_handler(struct work_struct *work) +{ + ospm_suspend_display(gpDrmDevice); +} +static void dsrexit_wq_handler(struct work_struct *work); +DECLARE_DELAYED_WORK(dsr_exitwork, dsrexit_wq_handler); +void dsrexit_wq_handler(struct work_struct *work) +{ + ospm_resume_display(gpDrmDevice->pdev); +} static void *gpvAnchor; extern int drm_psb_3D_vblank; @@ -989,6 +1010,10 @@ static MRST_BOOL MRSTLFBVSyncIHandler(MRSTLFB_DEVINFO *psDevInfo) psFlipItem = &psSwapChain->psVSyncFlips[psSwapChain->ulRemoveIndex]; } + + if (drm_psb_dsr) + schedule_delayed_work(&dsr_work, 10); + if (psSwapChain->ulRemoveIndex == psSwapChain->ulInsertIndex) bStatus = MRST_TRUE; ExitUnlock: @@ -1046,8 +1071,12 @@ static IMG_BOOL ProcessFlip(IMG_HANDLE hCmdCookie, psBuffer = (MRSTLFB_BUFFER*)psFlipCmd->hExtBuffer; psSwapChain = (MRSTLFB_SWAPCHAIN*) psFlipCmd->hExtSwapChain; + spin_lock_irqsave(&psDevInfo->sSwapChainLock, ulLockFlags); + if (drm_psb_dsr) + schedule_delayed_work(&dsr_exitwork, 0); + #if defined(MRST_USING_INTERRUPTS) if(!drm_psb_3D_vblank || psFlipCmd->ui32SwapInterval == 0 || psDevInfo->bFlushCommands) -- 2.7.4