Re: [Intel-gfx] [RFC v2] drm/i915/chv: Clip cursor for CHV pipe C HW Cursor pos < 0

2016-07-01 Thread Shobhit Kumar

On 06/29/2016 06:24 PM, Shobhit Kumar wrote:

From: Shobhit Kumar 

CHV pipe C hits underrun when we get negative crtc_x values of cursor.
To avoid this we clip and shift the cursor image by negative crtc_x
value.

v2: Make a copy of cursor plane state and allocate new gem object and fb
for clipped cursor and use that in case of negative cursor position

v3: Updated error handling
Pin the gem object before use.



Need someone to look at this patch. Daniel does this align with your 
suggestions ?


Regards
Shobhit


Signed-off-by: Akshu Agrawal 
Signed-off-by: Shobhit Kumar 
---
 drivers/gpu/drm/i915/i915_drv.h  |   7 ++
 drivers/gpu/drm/i915/intel_display.c | 131 ++-
 2 files changed, 137 insertions(+), 1 deletion(-)

diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h
index 724d34b..1e59c02 100644
--- a/drivers/gpu/drm/i915/i915_drv.h
+++ b/drivers/gpu/drm/i915/i915_drv.h
@@ -2041,6 +2041,13 @@ struct drm_i915_private {
struct intel_encoder *dig_port_map[I915_MAX_PORTS];

/*
+   * Temporary copy of cursor plane state for CHV PIPE_C
+   * Will be initialized only when crtc_x < 0 as there is a
+   * HW bug causing pipe underrun
+   */
+   struct intel_plane_state *cursor_state;
+
+   /*
 * NOTE: This is the dri1/ums dungeon, don't add stuff here. Your patch
 * will be rejected. Instead look for a better place.
 */
diff --git a/drivers/gpu/drm/i915/intel_display.c 
b/drivers/gpu/drm/i915/intel_display.c
index c3b5dc8..e6c103a 100644
--- a/drivers/gpu/drm/i915/intel_display.c
+++ b/drivers/gpu/drm/i915/intel_display.c
@@ -14456,6 +14456,132 @@ intel_update_cursor_plane(struct drm_plane *plane,
intel_crtc_update_cursor(crtc, state);
 }

+static void
+intel_update_chv_pipe_c_cursor_plane(struct drm_plane *plane,
+   const struct intel_crtc_state *crtc_state,
+   const struct intel_plane_state *state)
+{
+   struct drm_crtc *crtc = crtc_state->base.crtc;
+   struct intel_crtc *intel_crtc = to_intel_crtc(crtc);
+   struct drm_device *dev = plane->dev;
+   struct drm_i915_private *dev_priv = dev->dev_private;
+   struct drm_i915_gem_object *obj = intel_fb_obj(state->base.fb);
+   struct drm_i915_gem_object *cur_obj = NULL, *use_obj = NULL;
+   uint32_t addr;
+   struct intel_plane_state *cursor_state = dev_priv->cursor_state;
+   const struct intel_plane_state *use_state;
+   char __iomem *src, *dst;
+   bool pinned = true;
+
+   if (state->visible && state->base.crtc_x < 0) {
+   int bytes_per_pixel = state->base.fb->bits_per_pixel / 8;
+   int x = state->base.crtc_x;
+   int width = state->base.crtc_w;
+   int height = state->base.crtc_h;
+   struct drm_mode_fb_cmd2 mode_cmd = { 0 };
+   int i;
+
+   if (!cursor_state) {
+   cursor_state = kzalloc(sizeof(*cursor_state), 
GFP_KERNEL);
+   if (!cursor_state) {
+   use_state = state;
+   use_obj = obj;
+   goto update;
+   }
+
+   memcpy(cursor_state, state, sizeof(*state));
+
+   /* Allocate new gem object */
+   cur_obj = i915_gem_object_create(dev, obj->base.size);
+   if (IS_ERR(cur_obj))
+   goto gem_err;
+
+   mode_cmd.width = cursor_state->base.fb->width;
+   mode_cmd.height = cursor_state->base.fb->height;
+   mode_cmd.pitches[0] = cursor_state->base.fb->pitches[0];
+   mode_cmd.pixel_format = 
cursor_state->base.fb->pixel_format;
+
+   cursor_state->base.fb = intel_framebuffer_create(dev, 
&mode_cmd, cur_obj);
+   if (IS_ERR(cursor_state->base.fb)) {
+   
drm_gem_object_unreference_unlocked(&cur_obj->base);
+   goto gem_err;
+   }
+
+   if (i915_gem_obj_ggtt_pin(cur_obj, 0, 0) < 0) {
+   
drm_gem_object_unreference_unlocked(&cur_obj->base);
+   pinned = false;
+   goto cleanup;
+   }
+
+   dev_priv->cursor_state = cursor_state;
+   } else
+   cur_obj = intel_fb_obj(cursor_state->base.fb);
+
+   src = ioremap_wc(dev_priv->ggtt.mappable_base +
+   i915_gem_obj_ggtt_offset(obj),
+   obj->base.size);
+
+   dst = ioremap_wc(dev_priv->ggtt.mappable_

Re: [Intel-gfx] [RFC v2] drm/i915/chv: Clip cursor for CHV pipe C HW Cursor pos < 0

2016-07-08 Thread Shobhit Kumar
On Wed, Jun 29, 2016 at 6:24 PM, Shobhit Kumar
 wrote:
>
> From: Shobhit Kumar 
>
> CHV pipe C hits underrun when we get negative crtc_x values of cursor.
> To avoid this we clip and shift the cursor image by negative crtc_x
> value.
>
> v2: Make a copy of cursor plane state and allocate new gem object and fb
> for clipped cursor and use that in case of negative cursor position
>
> v3: Updated error handling
> Pin the gem object before use.

Summarizing the discussion with Ville and Chris on IRC few days back -
1. This indeed does break the uabi which expects coherent writing into
cursor plane (Chris)
2. Doing this with single buffer in kernel might result in tearing. We
will need triple buffering (Ville)
3. Some continuous rendering tools might break (Chris)
4. Animated cursor  might break (Chris). But then update plane call
should copy back the original buffer every time and animated cursor
should work as long as this is not filtered.

So still recommendation remains to use SW cursor, though in theory
clipping is possible but with additional complexity.

Regards
Shobhit

>
> Signed-off-by: Akshu Agrawal 
> Signed-off-by: Shobhit Kumar 
> ---
>  drivers/gpu/drm/i915/i915_drv.h  |   7 ++
>  drivers/gpu/drm/i915/intel_display.c | 131 
> ++-
>  2 files changed, 137 insertions(+), 1 deletion(-)
>
> diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h
> index 724d34b..1e59c02 100644
> --- a/drivers/gpu/drm/i915/i915_drv.h
> +++ b/drivers/gpu/drm/i915/i915_drv.h
> @@ -2041,6 +2041,13 @@ struct drm_i915_private {
> struct intel_encoder *dig_port_map[I915_MAX_PORTS];
>
> /*
> +   * Temporary copy of cursor plane state for CHV PIPE_C
> +   * Will be initialized only when crtc_x < 0 as there is a
> +   * HW bug causing pipe underrun
> +   */
> +   struct intel_plane_state *cursor_state;
> +
> +   /*
>  * NOTE: This is the dri1/ums dungeon, don't add stuff here. Your 
> patch
>  * will be rejected. Instead look for a better place.
>  */
> diff --git a/drivers/gpu/drm/i915/intel_display.c 
> b/drivers/gpu/drm/i915/intel_display.c
> index c3b5dc8..e6c103a 100644
> --- a/drivers/gpu/drm/i915/intel_display.c
> +++ b/drivers/gpu/drm/i915/intel_display.c
> @@ -14456,6 +14456,132 @@ intel_update_cursor_plane(struct drm_plane *plane,
> intel_crtc_update_cursor(crtc, state);
>  }
>
> +static void
> +intel_update_chv_pipe_c_cursor_plane(struct drm_plane *plane,
> +   const struct intel_crtc_state *crtc_state,
> +   const struct intel_plane_state *state)
> +{
> +   struct drm_crtc *crtc = crtc_state->base.crtc;
> +   struct intel_crtc *intel_crtc = to_intel_crtc(crtc);
> +   struct drm_device *dev = plane->dev;
> +   struct drm_i915_private *dev_priv = dev->dev_private;
> +   struct drm_i915_gem_object *obj = intel_fb_obj(state->base.fb);
> +   struct drm_i915_gem_object *cur_obj = NULL, *use_obj = NULL;
> +   uint32_t addr;
> +   struct intel_plane_state *cursor_state = dev_priv->cursor_state;
> +   const struct intel_plane_state *use_state;
> +   char __iomem *src, *dst;
> +   bool pinned = true;
> +
> +   if (state->visible && state->base.crtc_x < 0) {
> +   int bytes_per_pixel = state->base.fb->bits_per_pixel / 8;
> +   int x = state->base.crtc_x;
> +   int width = state->base.crtc_w;
> +   int height = state->base.crtc_h;
> +   struct drm_mode_fb_cmd2 mode_cmd = { 0 };
> +   int i;
> +
> +   if (!cursor_state) {
> +   cursor_state = kzalloc(sizeof(*cursor_state), 
> GFP_KERNEL);
> +   if (!cursor_state) {
> +   use_state = state;
> +   use_obj = obj;
> +   goto update;
> +   }
> +
> +   memcpy(cursor_state, state, sizeof(*state));
> +
> +   /* Allocate new gem object */
> +   cur_obj = i915_gem_object_create(dev, obj->base.size);
> +   if (IS_ERR(cur_obj))
> +   goto gem_err;
> +
> +   mode_cmd.width = cursor_state->base.fb->width;
> +   mode_cmd.height = cursor_state->base.fb->height;
> +   mode_cmd.pitches[0] = 
> cursor_state->base.fb->pitches[0];
> +   mode_cmd.pixel_format = 
> cursor_state->base.fb->pixel_format;

[Intel-gfx] [PATCH] drm/i915: Return -EPROBE_DEFER if we cannot get GPIO or PWM in dsi_init

2016-07-15 Thread Shobhit Kumar
On devices that have MIPI DSI panel control and PWM control comming from
CRC PMIC, we need the gpio and pwm exported from the intel_soc_pmic
driver. Defer probing for later in case we fail to get these devices.

v2: Rebased on latest drm-intel-nightly
Added failure check for pwm_get which got missed out

Signed-off-by: Shobhit Kumar 
---
 drivers/gpu/drm/i915/i915_drv.c  |  4 
 drivers/gpu/drm/i915/i915_drv.h  |  2 +-
 drivers/gpu/drm/i915/intel_display.c | 25 +++--
 drivers/gpu/drm/i915/intel_drv.h |  2 +-
 drivers/gpu/drm/i915/intel_dsi.c | 24 +---
 5 files changed, 42 insertions(+), 15 deletions(-)

diff --git a/drivers/gpu/drm/i915/i915_drv.c b/drivers/gpu/drm/i915/i915_drv.c
index b9a8117..9bfe0c8 100644
--- a/drivers/gpu/drm/i915/i915_drv.c
+++ b/drivers/gpu/drm/i915/i915_drv.c
@@ -648,6 +648,9 @@ static int i915_load_modeset_init(struct drm_device *dev)
/* Important: The output setup functions called by modeset_init need
 * working irqs for e.g. gmbus and dp aux transfers. */
intel_modeset_init(dev);
+   ret = intel_modeset_init(dev);
+   if (ret == -EPROBE_DEFER)
+   goto cleanup_deffered_probe;
 
intel_guc_init(dev);
 
@@ -675,6 +678,7 @@ cleanup_gem:
i915_gem_fini(dev);
 cleanup_irq:
intel_guc_fini(dev);
+cleanup_deffered_probe:
drm_irq_uninstall(dev);
intel_teardown_gmbus(dev);
 cleanup_csr:
diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h
index 03e1bfa..a9eed22 100644
--- a/drivers/gpu/drm/i915/i915_drv.h
+++ b/drivers/gpu/drm/i915/i915_drv.h
@@ -3778,7 +3778,7 @@ void intel_device_info_dump(struct drm_i915_private 
*dev_priv);
 
 /* modesetting */
 extern void intel_modeset_init_hw(struct drm_device *dev);
-extern void intel_modeset_init(struct drm_device *dev);
+extern int intel_modeset_init(struct drm_device *dev);
 extern void intel_modeset_gem_init(struct drm_device *dev);
 extern void intel_modeset_cleanup(struct drm_device *dev);
 extern int intel_connector_register(struct drm_connector *);
diff --git a/drivers/gpu/drm/i915/intel_display.c 
b/drivers/gpu/drm/i915/intel_display.c
index be3b2ca..b1250f2 100644
--- a/drivers/gpu/drm/i915/intel_display.c
+++ b/drivers/gpu/drm/i915/intel_display.c
@@ -14612,11 +14612,12 @@ static bool intel_crt_present(struct drm_device *dev)
return true;
 }
 
-static void intel_setup_outputs(struct drm_device *dev)
+static int intel_setup_outputs(struct drm_device *dev)
 {
struct drm_i915_private *dev_priv = to_i915(dev);
struct intel_encoder *encoder;
bool dpd_is_edp = false;
+   int ret = 0;
 
/*
 * intel_edp_init_connector() depends on this completing first, to
@@ -14638,7 +14639,9 @@ static void intel_setup_outputs(struct drm_device *dev)
intel_ddi_init(dev, PORT_B);
intel_ddi_init(dev, PORT_C);
 
-   intel_dsi_init(dev);
+   ret = intel_dsi_init(dev);
+   if (ret == -EPROBE_DEFER)
+   return ret;
} else if (HAS_DDI(dev)) {
int found;
 
@@ -14742,7 +14745,9 @@ static void intel_setup_outputs(struct drm_device *dev)
intel_hdmi_init(dev, CHV_HDMID, PORT_D);
}
 
-   intel_dsi_init(dev);
+   ret = intel_dsi_init(dev);
+   if (ret == -EPROBE_DEFER)
+   return ret;
} else if (!IS_GEN2(dev) && !IS_PINEVIEW(dev)) {
bool found = false;
 
@@ -14795,6 +14800,8 @@ static void intel_setup_outputs(struct drm_device *dev)
intel_init_pch_refclk(dev);
 
drm_helper_move_panel_connectors_to_head(dev);
+
+   return 0;
 }
 
 static void intel_user_framebuffer_destroy(struct drm_framebuffer *fb)
@@ -15539,7 +15546,7 @@ fail:
drm_modeset_acquire_fini(&ctx);
 }
 
-void intel_modeset_init(struct drm_device *dev)
+int intel_modeset_init(struct drm_device *dev)
 {
struct drm_i915_private *dev_priv = to_i915(dev);
struct i915_ggtt *ggtt = &dev_priv->ggtt;
@@ -15564,7 +15571,7 @@ void intel_modeset_init(struct drm_device *dev)
intel_init_pm(dev);
 
if (INTEL_INFO(dev)->num_pipes == 0)
-   return;
+   return 0;
 
/*
 * There may be no VBT; and if the BIOS enabled SSC we can
@@ -15632,7 +15639,11 @@ void intel_modeset_init(struct drm_device *dev)
 
/* Just disable it once at startup */
i915_disable_vga(dev);
-   intel_setup_outputs(dev);
+
+   /* Check if we encountered -EPROBE_DEFER while initializing DSI */
+   ret = intel_setup_outputs(dev);
+   if (ret)
+   return ret;
 
drm_modeset_lock_all(dev);
intel_modeset_setup_hw_state(dev);
@@ -15667,6 +15678,8 @@ void intel_modeset_init(struct drm_device *dev)
 * since the watermark calc

Re: [Intel-gfx] [PATCH] drm/i915: Return -EPROBE_DEFER if we cannot get GPIO or PWM in dsi_init

2016-07-15 Thread Shobhit Kumar
On Fri, Jul 15, 2016 at 2:33 PM, Shobhit Kumar  wrote:
> On devices that have MIPI DSI panel control and PWM control comming from
> CRC PMIC, we need the gpio and pwm exported from the intel_soc_pmic
> driver. Defer probing for later in case we fail to get these devices.
>
> v2: Rebased on latest drm-intel-nightly
> Added failure check for pwm_get which got missed out
>

Just an attempt and is untested yet because of lack of device which
use CRC PMIC or LPSS. Hopefully can get some testing help from Stephen
and  Viric who have such devices.

Regards
Shobhit

> Signed-off-by: Shobhit Kumar 
> ---
>  drivers/gpu/drm/i915/i915_drv.c  |  4 
>  drivers/gpu/drm/i915/i915_drv.h  |  2 +-
>  drivers/gpu/drm/i915/intel_display.c | 25 +++--
>  drivers/gpu/drm/i915/intel_drv.h |  2 +-
>  drivers/gpu/drm/i915/intel_dsi.c | 24 +---
>  5 files changed, 42 insertions(+), 15 deletions(-)
>
> diff --git a/drivers/gpu/drm/i915/i915_drv.c b/drivers/gpu/drm/i915/i915_drv.c
> index b9a8117..9bfe0c8 100644
> --- a/drivers/gpu/drm/i915/i915_drv.c
> +++ b/drivers/gpu/drm/i915/i915_drv.c
> @@ -648,6 +648,9 @@ static int i915_load_modeset_init(struct drm_device *dev)
> /* Important: The output setup functions called by modeset_init need
>  * working irqs for e.g. gmbus and dp aux transfers. */
> intel_modeset_init(dev);
> +   ret = intel_modeset_init(dev);
> +   if (ret == -EPROBE_DEFER)
> +   goto cleanup_deffered_probe;
>
> intel_guc_init(dev);
>
> @@ -675,6 +678,7 @@ cleanup_gem:
> i915_gem_fini(dev);
>  cleanup_irq:
> intel_guc_fini(dev);
> +cleanup_deffered_probe:
> drm_irq_uninstall(dev);
> intel_teardown_gmbus(dev);
>  cleanup_csr:
> diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h
> index 03e1bfa..a9eed22 100644
> --- a/drivers/gpu/drm/i915/i915_drv.h
> +++ b/drivers/gpu/drm/i915/i915_drv.h
> @@ -3778,7 +3778,7 @@ void intel_device_info_dump(struct drm_i915_private 
> *dev_priv);
>
>  /* modesetting */
>  extern void intel_modeset_init_hw(struct drm_device *dev);
> -extern void intel_modeset_init(struct drm_device *dev);
> +extern int intel_modeset_init(struct drm_device *dev);
>  extern void intel_modeset_gem_init(struct drm_device *dev);
>  extern void intel_modeset_cleanup(struct drm_device *dev);
>  extern int intel_connector_register(struct drm_connector *);
> diff --git a/drivers/gpu/drm/i915/intel_display.c 
> b/drivers/gpu/drm/i915/intel_display.c
> index be3b2ca..b1250f2 100644
> --- a/drivers/gpu/drm/i915/intel_display.c
> +++ b/drivers/gpu/drm/i915/intel_display.c
> @@ -14612,11 +14612,12 @@ static bool intel_crt_present(struct drm_device 
> *dev)
> return true;
>  }
>
> -static void intel_setup_outputs(struct drm_device *dev)
> +static int intel_setup_outputs(struct drm_device *dev)
>  {
> struct drm_i915_private *dev_priv = to_i915(dev);
> struct intel_encoder *encoder;
> bool dpd_is_edp = false;
> +   int ret = 0;
>
> /*
>  * intel_edp_init_connector() depends on this completing first, to
> @@ -14638,7 +14639,9 @@ static void intel_setup_outputs(struct drm_device 
> *dev)
> intel_ddi_init(dev, PORT_B);
> intel_ddi_init(dev, PORT_C);
>
> -   intel_dsi_init(dev);
> +   ret = intel_dsi_init(dev);
> +   if (ret == -EPROBE_DEFER)
> +   return ret;
> } else if (HAS_DDI(dev)) {
> int found;
>
> @@ -14742,7 +14745,9 @@ static void intel_setup_outputs(struct drm_device 
> *dev)
> intel_hdmi_init(dev, CHV_HDMID, PORT_D);
> }
>
> -   intel_dsi_init(dev);
> +   ret = intel_dsi_init(dev);
> +   if (ret == -EPROBE_DEFER)
> +   return ret;
> } else if (!IS_GEN2(dev) && !IS_PINEVIEW(dev)) {
> bool found = false;
>
> @@ -14795,6 +14800,8 @@ static void intel_setup_outputs(struct drm_device 
> *dev)
> intel_init_pch_refclk(dev);
>
> drm_helper_move_panel_connectors_to_head(dev);
> +
> +   return 0;
>  }
>
>  static void intel_user_framebuffer_destroy(struct drm_framebuffer *fb)
> @@ -15539,7 +15546,7 @@ fail:
> drm_modeset_acquire_fini(&ctx);
>  }
>
> -void intel_modeset_init(struct drm_device *dev)
> +int intel_modeset_init(struct drm_device *dev)
>  {
> struct drm_i915_private *dev_priv = to_i915(dev);
> struct i915_ggtt *ggtt = &dev_priv->ggtt;

Re: [Intel-gfx] [PATCH] drm/i915: Return -EPROBE_DEFER if we cannot get GPIO or PWM in dsi_init

2016-07-16 Thread Shobhit Kumar
On Sat, Jul 16, 2016 at 3:12 AM, Stephen J  wrote:
> On Fri, Jul 15, 2016 at 3:08 AM, Shobhit Kumar  wrote:
>>
>> On Fri, Jul 15, 2016 at 2:33 PM, Shobhit Kumar  
>> wrote:
>> > On devices that have MIPI DSI panel control and PWM control comming from
>> > CRC PMIC, we need the gpio and pwm exported from the intel_soc_pmic
>> > driver. Defer probing for later in case we fail to get these devices.
>> >
>> > v2: Rebased on latest drm-intel-nightly
>> > Added failure check for pwm_get which got missed out
>> >
>>
>> [snip]
>>
>> > diff --git a/drivers/gpu/drm/i915/i915_drv.c 
>> > b/drivers/gpu/drm/i915/i915_drv.c
>> > index b9a8117..9bfe0c8 100644
>> > --- a/drivers/gpu/drm/i915/i915_drv.c
>> > +++ b/drivers/gpu/drm/i915/i915_drv.c
>> > @@ -648,6 +648,9 @@ static int i915_load_modeset_init(struct drm_device 
>> > *dev)
>> > /* Important: The output setup functions called by modeset_init 
>> > need
>> >  * working irqs for e.g. gmbus and dp aux transfers. */
>> > intel_modeset_init(dev);
>> > +   ret = intel_modeset_init(dev);
>> > +   if (ret == -EPROBE_DEFER)
>> > +   goto cleanup_deffered_probe;
>
> Did you intend to call intel_modeset_init twice? In my tests, I
> removed the first copy because it seemed like a mistake.
>

Nope I did not. It was a mistake. Thanks for pointing out.

>> >
>> > intel_guc_init(dev);
>> >
>> > @@ -675,6 +678,7 @@ cleanup_gem:
>> > i915_gem_fini(dev);
>> >  cleanup_irq:
>> > intel_guc_fini(dev);
>> > +cleanup_deffered_probe:
>> > drm_irq_uninstall(dev);
>> > intel_teardown_gmbus(dev);
>> >  cleanup_csr:
>> > diff --git a/drivers/gpu/drm/i915/i915_drv.h 
>> > b/drivers/gpu/drm/i915/i915_drv.h
>> > index 03e1bfa..a9eed22 100644
>> > --- a/drivers/gpu/drm/i915/i915_drv.h
>> > +++ b/drivers/gpu/drm/i915/i915_drv.h
>> > @@ -3778,7 +3778,7 @@ void intel_device_info_dump(struct drm_i915_private 
>> > *dev_priv);
>> >
>> >  /* modesetting */
>> >  extern void intel_modeset_init_hw(struct drm_device *dev);
>> > -extern void intel_modeset_init(struct drm_device *dev);
>> > +extern int intel_modeset_init(struct drm_device *dev);
>> >  extern void intel_modeset_gem_init(struct drm_device *dev);
>> >  extern void intel_modeset_cleanup(struct drm_device *dev);
>> >  extern int intel_connector_register(struct drm_connector *);
>> > diff --git a/drivers/gpu/drm/i915/intel_display.c 
>> > b/drivers/gpu/drm/i915/intel_display.c
>> > index be3b2ca..b1250f2 100644
>> > [snip]
>
> When testing on drm-intel-nightly, my system froze with your patch. I
> can't get a full dmesg because I haven't yet found a way to trigger
> the problem after I can get an ssh session up.
>
> The relevant logs I see before freeze are:
> [drm] Initialized drm 1.1.0 20060810
> [drm] Memory usable by graphics device = 2048M
> fb: switching to inteldrmfb from EFI VGA
>
> console is stuck at this point, my guess is that modeset fails and
> that isn't handled well. The screen does not go black, the log
> messages just stay on screen indefinitely.

Will try to force deferred probe on one of my device which has serial
console to get the serial logs and debug deferred probe in general.

Regards
Shobhit

>
> If I blacklist i915 and let X load the module (or manually load it
> later), everything seems to run fine and backlight works, but that was
> also true before applying the patch.
>
> Regards,
> Stephen
___
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/intel-gfx


Re: [Intel-gfx] [PATCH 2/2] drm/i915: Crop cursor image for CHV pipe C cursor issue

2016-06-27 Thread Shobhit Kumar
On Mon, Jun 13, 2016 at 7:52 PM, Daniel Vetter  wrote:
> On Fri, Jun 10, 2016 at 03:14:36PM +0530, Agrawal, Akshu wrote:
>> On 6/8/2016 2:10 PM, Daniel Vetter wrote:
>> > On Wed, Jun 08, 2016 at 01:57:44PM +0530, Akshu Agrawal wrote:
>> > > CHV pipe C hits underrun when we get -ve X values of cursor. To avoid
>> > > this we crop the cursor image for by -ve X value and thus use '0' as
>> > > least X value.
>> >
>> > You're talking about "-ve" here and there's absolutely no "-ve" anywhere
>> > in your patch. That makes your commit message non-understandable.
>>
>> Will change -ve to "negative" for better readability.
>>
>> >
>> > But I think I get what you're doing here, and nope, you can't override the
>> > cursor image like that. If we go with this w/a then you need to allocate a
>> > new cursor gem bo instead. This is userspace-visible.
>>
>> Can't we use the same gem bo? As we are calling
>> "i915_gem_object_set_to_gtt_domain" to get write access for CPU after
>> unbinding from GTT.
>
> Userspace can write to the underlying bo without telling us. That'll cause
> tearing. And it could also read from it, which would result in even more
> serious bugs.
>
> We can't just change userspace-visible state for a w/a. Same reasoning
> applies to the crtc_state stuff. Again we need copies, to avoid
> accidentally confusion userspace.
>

Agreed Daniel. Though chances user space doing something like this are
less, but nevertheless it can happen.

> With all those copies it's probably best to write a special
> atomic_update_plane function for cursor pipe C, to avoid spreading all of
> them all over the driver.

Is implementing a intel_chv_update_pipe_c_cursor_plane and
initializing that as the update_plane callback in case of PIPE C on
CHV during cursor plane creation is what you have in mind ? We can
then implement the copies inside this function. No too sure on the
atomic path so just want to confirm if this will work well.

Regards
Shobhit

> -Daniel
>
>>
>> Regards,
>> Akshu
>> >
>> > For similar reasons you're also not allowed to change crtc->state.
>> > -Daniel
>> >
>> > > Signed-off-by: Akshu Agrawal 
>> > > ---
>> > >  drivers/gpu/drm/i915/intel_display.c | 113 
>> > > +++
>> > >  drivers/gpu/drm/i915/intel_drv.h |   3 +
>> > >  2 files changed, 116 insertions(+)
>> > >
>> > > diff --git a/drivers/gpu/drm/i915/intel_display.c 
>> > > b/drivers/gpu/drm/i915/intel_display.c
>> > > index bca9245..e6e6568 100644
>> > > --- a/drivers/gpu/drm/i915/intel_display.c
>> > > +++ b/drivers/gpu/drm/i915/intel_display.c
>> > > @@ -14279,6 +14279,81 @@ void intel_create_rotation_property(struct 
>> > > drm_device *dev, struct intel_plane *
>> > >   plane->base.state->rotation);
>> > >  }
>> > >
>> > > +static void vlv_unpin_buffer_obj(struct drm_i915_gem_object *obj,
>> > > +   char __iomem *buffer_start)
>> > > +{
>> > > + iounmap(buffer_start);
>> > > + i915_gem_object_ggtt_unpin(obj);
>> > > +}
>> > > +
>> > > +static char __iomem *vlv_pin_and_map_buffer_obj
>> > > + (struct drm_i915_gem_object *obj)
>> > > +{
>> > > + struct drm_i915_private *dev_priv = obj->base.dev->dev_private;
>> > > + char __iomem *buffer_start;
>> > > + int ret;
>> > > +
>> > > + ret = i915_gem_obj_ggtt_pin(obj, PAGE_SIZE, PIN_MAPPABLE);
>> > > + if (ret)
>> > > + return NULL;
>> > > +
>> > > + ret = i915_gem_object_set_to_gtt_domain(obj, true);
>> > > + if (ret) {
>> > > + i915_gem_object_ggtt_unpin(obj);
>> > > + return NULL;
>> > > + }
>> > > +
>> > > + buffer_start = ioremap_wc(dev_priv->gtt.mappable_base +
>> > > + i915_gem_obj_ggtt_offset(obj), obj->base.size);
>> > > + if (buffer_start == NULL) {
>> > > + i915_gem_object_ggtt_unpin(obj);
>> > > + return NULL;
>> > > + }
>> > > +
>> > > + return buffer_start;
>> > > +}
>> > > +
>> > > +static int vlv_cursor_crop(struct intel_plane_state *state,
>> > > +   int prev_x)
>> > > +{
>> > > + struct drm_i915_gem_object *obj = intel_fb_obj(state->base.fb);
>> > > + struct drm_framebuffer *fb = state->base.fb;
>> > > + char __iomem *buffer = state->vlv_cursor_image;
>> > > + char __iomem *base, *cursor_base;
>> > > + int size = obj->base.size;
>> > > + int i, x = state->base.crtc_x;
>> > > + int bytes_per_pixel = fb->bits_per_pixel / 8;
>> > > +
>> > > + base = vlv_pin_and_map_buffer_obj(obj);
>> > > + if (base == NULL)
>> > > + return -ENOMEM;
>> > > +
>> > > + if (prev_x >= 0) {
>> > > + if (buffer != NULL)
>> > > + kfree(buffer);
>> > > + buffer = kzalloc(size, GFP_KERNEL);
>> > > + state->vlv_cursor_image = buffer;
>> > > + if (buffer == NULL)
>> > > + return -ENOMEM;
>> > > + memcpy(buffer, base, size);
>> > > + }
>> > > + cursor_base = buffer;
>> > > + x = -x;
>> > > + for (i = 0; i < state->base.crtc_h; i++) {
>> > > + cursor_b

[Intel-gfx] [RFC] drm/i915/chv: Clip cursor for CHV pipe C HW Cursor pos < 0

2016-06-28 Thread Shobhit Kumar
From: Shobhit Kumar 

CHV pipe C hits underrun when we get negative crtc_x values of cursor.
To avoid this we clip and shift the cursor image by negative crtc_x
value.

v2: Make a copy of cursor plane state and allocate new gem object and fb
for clipped cursor and use that in case of negative cursor position

Signed-off-by: Akshu Agrawal 
Signed-off-by: Shobhit Kumar 
---
 drivers/gpu/drm/i915/i915_drv.h  |   7 ++
 drivers/gpu/drm/i915/intel_display.c | 122 ++-
 2 files changed, 128 insertions(+), 1 deletion(-)

diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h
index 724d34b..1e59c02 100644
--- a/drivers/gpu/drm/i915/i915_drv.h
+++ b/drivers/gpu/drm/i915/i915_drv.h
@@ -2041,6 +2041,13 @@ struct drm_i915_private {
struct intel_encoder *dig_port_map[I915_MAX_PORTS];
 
/*
+   * Temporary copy of cursor plane state for CHV PIPE_C
+   * Will be initialized only when crtc_x < 0 as there is a
+   * HW bug causing pipe underrun
+   */
+   struct intel_plane_state *cursor_state;
+
+   /*
 * NOTE: This is the dri1/ums dungeon, don't add stuff here. Your patch
 * will be rejected. Instead look for a better place.
 */
diff --git a/drivers/gpu/drm/i915/intel_display.c 
b/drivers/gpu/drm/i915/intel_display.c
index c3b5dc8..c4988d5 100644
--- a/drivers/gpu/drm/i915/intel_display.c
+++ b/drivers/gpu/drm/i915/intel_display.c
@@ -14456,6 +14456,123 @@ intel_update_cursor_plane(struct drm_plane *plane,
intel_crtc_update_cursor(crtc, state);
 }
 
+static void
+intel_update_chv_pipe_c_cursor_plane(struct drm_plane *plane,
+   const struct intel_crtc_state *crtc_state,
+   const struct intel_plane_state *state)
+{
+   struct drm_crtc *crtc = crtc_state->base.crtc;
+   struct intel_crtc *intel_crtc = to_intel_crtc(crtc);
+   struct drm_device *dev = plane->dev;
+   struct drm_i915_private *dev_priv = dev->dev_private;
+   struct drm_i915_gem_object *obj = intel_fb_obj(state->base.fb);
+   struct drm_i915_gem_object *cur_obj = NULL, *use_obj = NULL;
+   uint32_t addr;
+   struct intel_plane_state *cursor_state = dev_priv->cursor_state;
+   const struct intel_plane_state *use_state;
+   char __iomem *src, *dst;
+
+   if (state->visible && state->base.crtc_x < 0) {
+   int bytes_per_pixel = state->base.fb->bits_per_pixel / 8;
+   int x = state->base.crtc_x;
+   int width = state->base.crtc_w;
+   int height = state->base.crtc_h;
+   struct drm_mode_fb_cmd2 mode_cmd = { 0 };
+   int i;
+
+   if (!cursor_state) {
+   cursor_state = kzalloc(sizeof(*cursor_state), 
GFP_KERNEL);
+   if (!cursor_state) {
+   use_state = state;
+   use_obj = obj;
+   goto update;
+   }
+
+   memcpy(cursor_state, state, sizeof(*state));
+   cursor_state->base.crtc_x = 0;
+
+   /* Allocate new gem object */
+   cur_obj = i915_gem_object_create(dev, obj->base.size);
+   if (IS_ERR(cur_obj)) {
+   kfree(cursor_state);
+   use_state = state;
+   use_obj = obj;
+   goto update;
+   }
+
+   mode_cmd.width = cursor_state->base.fb->width;
+   mode_cmd.height = cursor_state->base.fb->height;
+   mode_cmd.pitches[0] = cursor_state->base.fb->pitches[0];
+   mode_cmd.pixel_format = 
cursor_state->base.fb->pixel_format;
+
+   cursor_state->base.fb = intel_framebuffer_create(dev, 
&mode_cmd, cur_obj);
+   if (IS_ERR(cursor_state->base.fb)) {
+   
drm_gem_object_unreference_unlocked(&cur_obj->base);
+   kfree(cursor_state);
+   use_state = state;
+   use_obj = obj;
+   goto update;
+   }
+
+   dev_priv->cursor_state = cursor_state;
+   } else
+   cur_obj = intel_fb_obj(cursor_state->base.fb);
+
+   src = ioremap_wc(dev_priv->ggtt.mappable_base +
+   i915_gem_obj_ggtt_offset(obj),
+   obj->base.size);
+
+   dst = ioremap_wc(dev_priv->ggtt.mappable_base +
+   i915_gem_obj_ggtt_offset(cur_obj),
+   cur_obj->base.size);
+
+   /*

Re: [Intel-gfx] [RFC] drm/i915/chv: Clip cursor for CHV pipe C HW Cursor pos < 0

2016-06-28 Thread Shobhit Kumar

Daniel,

On 06/28/2016 05:57 PM, Shobhit Kumar wrote:

From: Shobhit Kumar 

CHV pipe C hits underrun when we get negative crtc_x values of cursor.
To avoid this we clip and shift the cursor image by negative crtc_x
value.

v2: Make a copy of cursor plane state and allocate new gem object and fb
for clipped cursor and use that in case of negative cursor position



This patch is not yet tested and most likely not even complete and is 
sent for early review of the approach. Will test it and update the 
status here.


Regards
Shobhit


Signed-off-by: Akshu Agrawal 
Signed-off-by: Shobhit Kumar 
---
 drivers/gpu/drm/i915/i915_drv.h  |   7 ++
 drivers/gpu/drm/i915/intel_display.c | 122 ++-
 2 files changed, 128 insertions(+), 1 deletion(-)

diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h
index 724d34b..1e59c02 100644
--- a/drivers/gpu/drm/i915/i915_drv.h
+++ b/drivers/gpu/drm/i915/i915_drv.h
@@ -2041,6 +2041,13 @@ struct drm_i915_private {
struct intel_encoder *dig_port_map[I915_MAX_PORTS];

/*
+   * Temporary copy of cursor plane state for CHV PIPE_C
+   * Will be initialized only when crtc_x < 0 as there is a
+   * HW bug causing pipe underrun
+   */
+   struct intel_plane_state *cursor_state;
+
+   /*
 * NOTE: This is the dri1/ums dungeon, don't add stuff here. Your patch
 * will be rejected. Instead look for a better place.
 */
diff --git a/drivers/gpu/drm/i915/intel_display.c 
b/drivers/gpu/drm/i915/intel_display.c
index c3b5dc8..c4988d5 100644
--- a/drivers/gpu/drm/i915/intel_display.c
+++ b/drivers/gpu/drm/i915/intel_display.c
@@ -14456,6 +14456,123 @@ intel_update_cursor_plane(struct drm_plane *plane,
intel_crtc_update_cursor(crtc, state);
 }

+static void
+intel_update_chv_pipe_c_cursor_plane(struct drm_plane *plane,
+   const struct intel_crtc_state *crtc_state,
+   const struct intel_plane_state *state)
+{
+   struct drm_crtc *crtc = crtc_state->base.crtc;
+   struct intel_crtc *intel_crtc = to_intel_crtc(crtc);
+   struct drm_device *dev = plane->dev;
+   struct drm_i915_private *dev_priv = dev->dev_private;
+   struct drm_i915_gem_object *obj = intel_fb_obj(state->base.fb);
+   struct drm_i915_gem_object *cur_obj = NULL, *use_obj = NULL;
+   uint32_t addr;
+   struct intel_plane_state *cursor_state = dev_priv->cursor_state;
+   const struct intel_plane_state *use_state;
+   char __iomem *src, *dst;
+
+   if (state->visible && state->base.crtc_x < 0) {
+   int bytes_per_pixel = state->base.fb->bits_per_pixel / 8;
+   int x = state->base.crtc_x;
+   int width = state->base.crtc_w;
+   int height = state->base.crtc_h;
+   struct drm_mode_fb_cmd2 mode_cmd = { 0 };
+   int i;
+
+   if (!cursor_state) {
+   cursor_state = kzalloc(sizeof(*cursor_state), 
GFP_KERNEL);
+   if (!cursor_state) {
+   use_state = state;
+   use_obj = obj;
+   goto update;
+   }
+
+   memcpy(cursor_state, state, sizeof(*state));
+   cursor_state->base.crtc_x = 0;
+
+   /* Allocate new gem object */
+   cur_obj = i915_gem_object_create(dev, obj->base.size);
+   if (IS_ERR(cur_obj)) {
+   kfree(cursor_state);
+   use_state = state;
+   use_obj = obj;
+   goto update;
+   }
+
+   mode_cmd.width = cursor_state->base.fb->width;
+   mode_cmd.height = cursor_state->base.fb->height;
+   mode_cmd.pitches[0] = cursor_state->base.fb->pitches[0];
+   mode_cmd.pixel_format = 
cursor_state->base.fb->pixel_format;
+
+   cursor_state->base.fb = intel_framebuffer_create(dev, 
&mode_cmd, cur_obj);
+   if (IS_ERR(cursor_state->base.fb)) {
+   
drm_gem_object_unreference_unlocked(&cur_obj->base);
+   kfree(cursor_state);
+   use_state = state;
+   use_obj = obj;
+   goto update;
+   }
+
+   dev_priv->cursor_state = cursor_state;
+   } else
+   cur_obj = intel_fb_obj(cursor_state->base.fb);
+
+   src = ioremap_wc(dev_priv->ggtt.mappable_base +
+   i915_gem_obj_ggtt_offset(obj),
+

[Intel-gfx] [RFC v2] drm/i915/chv: Clip cursor for CHV pipe C HW Cursor pos < 0

2016-06-29 Thread Shobhit Kumar
From: Shobhit Kumar 

CHV pipe C hits underrun when we get negative crtc_x values of cursor.
To avoid this we clip and shift the cursor image by negative crtc_x
value.

v2: Make a copy of cursor plane state and allocate new gem object and fb
for clipped cursor and use that in case of negative cursor position

v3: Updated error handling
Pin the gem object before use.

Signed-off-by: Akshu Agrawal 
Signed-off-by: Shobhit Kumar 
---
 drivers/gpu/drm/i915/i915_drv.h  |   7 ++
 drivers/gpu/drm/i915/intel_display.c | 131 ++-
 2 files changed, 137 insertions(+), 1 deletion(-)

diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h
index 724d34b..1e59c02 100644
--- a/drivers/gpu/drm/i915/i915_drv.h
+++ b/drivers/gpu/drm/i915/i915_drv.h
@@ -2041,6 +2041,13 @@ struct drm_i915_private {
struct intel_encoder *dig_port_map[I915_MAX_PORTS];
 
/*
+   * Temporary copy of cursor plane state for CHV PIPE_C
+   * Will be initialized only when crtc_x < 0 as there is a
+   * HW bug causing pipe underrun
+   */
+   struct intel_plane_state *cursor_state;
+
+   /*
 * NOTE: This is the dri1/ums dungeon, don't add stuff here. Your patch
 * will be rejected. Instead look for a better place.
 */
diff --git a/drivers/gpu/drm/i915/intel_display.c 
b/drivers/gpu/drm/i915/intel_display.c
index c3b5dc8..e6c103a 100644
--- a/drivers/gpu/drm/i915/intel_display.c
+++ b/drivers/gpu/drm/i915/intel_display.c
@@ -14456,6 +14456,132 @@ intel_update_cursor_plane(struct drm_plane *plane,
intel_crtc_update_cursor(crtc, state);
 }
 
+static void
+intel_update_chv_pipe_c_cursor_plane(struct drm_plane *plane,
+   const struct intel_crtc_state *crtc_state,
+   const struct intel_plane_state *state)
+{
+   struct drm_crtc *crtc = crtc_state->base.crtc;
+   struct intel_crtc *intel_crtc = to_intel_crtc(crtc);
+   struct drm_device *dev = plane->dev;
+   struct drm_i915_private *dev_priv = dev->dev_private;
+   struct drm_i915_gem_object *obj = intel_fb_obj(state->base.fb);
+   struct drm_i915_gem_object *cur_obj = NULL, *use_obj = NULL;
+   uint32_t addr;
+   struct intel_plane_state *cursor_state = dev_priv->cursor_state;
+   const struct intel_plane_state *use_state;
+   char __iomem *src, *dst;
+   bool pinned = true;
+
+   if (state->visible && state->base.crtc_x < 0) {
+   int bytes_per_pixel = state->base.fb->bits_per_pixel / 8;
+   int x = state->base.crtc_x;
+   int width = state->base.crtc_w;
+   int height = state->base.crtc_h;
+   struct drm_mode_fb_cmd2 mode_cmd = { 0 };
+   int i;
+
+   if (!cursor_state) {
+   cursor_state = kzalloc(sizeof(*cursor_state), 
GFP_KERNEL);
+   if (!cursor_state) {
+   use_state = state;
+   use_obj = obj;
+   goto update;
+   }
+
+   memcpy(cursor_state, state, sizeof(*state));
+
+   /* Allocate new gem object */
+   cur_obj = i915_gem_object_create(dev, obj->base.size);
+   if (IS_ERR(cur_obj))
+   goto gem_err;
+
+   mode_cmd.width = cursor_state->base.fb->width;
+   mode_cmd.height = cursor_state->base.fb->height;
+   mode_cmd.pitches[0] = cursor_state->base.fb->pitches[0];
+   mode_cmd.pixel_format = 
cursor_state->base.fb->pixel_format;
+
+   cursor_state->base.fb = intel_framebuffer_create(dev, 
&mode_cmd, cur_obj);
+   if (IS_ERR(cursor_state->base.fb)) {
+   
drm_gem_object_unreference_unlocked(&cur_obj->base);
+   goto gem_err;
+   }
+
+   if (i915_gem_obj_ggtt_pin(cur_obj, 0, 0) < 0) {
+   
drm_gem_object_unreference_unlocked(&cur_obj->base);
+   pinned = false;
+   goto cleanup;
+   }
+
+   dev_priv->cursor_state = cursor_state;
+   } else
+   cur_obj = intel_fb_obj(cursor_state->base.fb);
+
+   src = ioremap_wc(dev_priv->ggtt.mappable_base +
+   i915_gem_obj_ggtt_offset(obj),
+   obj->base.size);
+
+   dst = ioremap_wc(dev_priv->ggtt.mappable_base +
+   i915_gem_obj_ggtt_offset(cur_obj),
+   cur_obj->base.size);
+
+   /* shif

Re: [Intel-gfx] [RFC v2] drm/i915/chv: Clip cursor for CHV pipe C HW Cursor pos < 0

2016-06-29 Thread Shobhit Kumar

On 06/29/2016 06:24 PM, Shobhit Kumar wrote:

From: Shobhit Kumar 

CHV pipe C hits underrun when we get negative crtc_x values of cursor.
To avoid this we clip and shift the cursor image by negative crtc_x
value.

v2: Make a copy of cursor plane state and allocate new gem object and fb
for clipped cursor and use that in case of negative cursor position

v3: Updated error handling
Pin the gem object before use.


I tested a modified version of this on 3.18 kernel on ChromeOS. Does 
work fine, but few WARN dumps from might_sleep() in atomic context while 
allocating cursor gem bo. I can allocate it one time during plane 
creation but how do I know the size of incoming bo ? If I allocate for 
say large cursor 256x256, ioremap_wc also has same WARN dumps. Need to 
remap in update function. Any hints how to go about it ? Maybe I should 
do this hack in check_plane rather than update plane ?


Regards
Shobhit



Signed-off-by: Akshu Agrawal 
Signed-off-by: Shobhit Kumar 
---
 drivers/gpu/drm/i915/i915_drv.h  |   7 ++
 drivers/gpu/drm/i915/intel_display.c | 131 ++-
 2 files changed, 137 insertions(+), 1 deletion(-)

diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h
index 724d34b..1e59c02 100644
--- a/drivers/gpu/drm/i915/i915_drv.h
+++ b/drivers/gpu/drm/i915/i915_drv.h
@@ -2041,6 +2041,13 @@ struct drm_i915_private {
struct intel_encoder *dig_port_map[I915_MAX_PORTS];

/*
+   * Temporary copy of cursor plane state for CHV PIPE_C
+   * Will be initialized only when crtc_x < 0 as there is a
+   * HW bug causing pipe underrun
+   */
+   struct intel_plane_state *cursor_state;
+
+   /*
 * NOTE: This is the dri1/ums dungeon, don't add stuff here. Your patch
 * will be rejected. Instead look for a better place.
 */
diff --git a/drivers/gpu/drm/i915/intel_display.c 
b/drivers/gpu/drm/i915/intel_display.c
index c3b5dc8..e6c103a 100644
--- a/drivers/gpu/drm/i915/intel_display.c
+++ b/drivers/gpu/drm/i915/intel_display.c
@@ -14456,6 +14456,132 @@ intel_update_cursor_plane(struct drm_plane *plane,
intel_crtc_update_cursor(crtc, state);
 }

+static void
+intel_update_chv_pipe_c_cursor_plane(struct drm_plane *plane,
+   const struct intel_crtc_state *crtc_state,
+   const struct intel_plane_state *state)
+{
+   struct drm_crtc *crtc = crtc_state->base.crtc;
+   struct intel_crtc *intel_crtc = to_intel_crtc(crtc);
+   struct drm_device *dev = plane->dev;
+   struct drm_i915_private *dev_priv = dev->dev_private;
+   struct drm_i915_gem_object *obj = intel_fb_obj(state->base.fb);
+   struct drm_i915_gem_object *cur_obj = NULL, *use_obj = NULL;
+   uint32_t addr;
+   struct intel_plane_state *cursor_state = dev_priv->cursor_state;
+   const struct intel_plane_state *use_state;
+   char __iomem *src, *dst;
+   bool pinned = true;
+
+   if (state->visible && state->base.crtc_x < 0) {
+   int bytes_per_pixel = state->base.fb->bits_per_pixel / 8;
+   int x = state->base.crtc_x;
+   int width = state->base.crtc_w;
+   int height = state->base.crtc_h;
+   struct drm_mode_fb_cmd2 mode_cmd = { 0 };
+   int i;
+
+   if (!cursor_state) {
+   cursor_state = kzalloc(sizeof(*cursor_state), 
GFP_KERNEL);
+   if (!cursor_state) {
+   use_state = state;
+   use_obj = obj;
+   goto update;
+   }
+
+   memcpy(cursor_state, state, sizeof(*state));
+
+   /* Allocate new gem object */
+   cur_obj = i915_gem_object_create(dev, obj->base.size);
+   if (IS_ERR(cur_obj))
+   goto gem_err;
+
+   mode_cmd.width = cursor_state->base.fb->width;
+   mode_cmd.height = cursor_state->base.fb->height;
+   mode_cmd.pitches[0] = cursor_state->base.fb->pitches[0];
+   mode_cmd.pixel_format = 
cursor_state->base.fb->pixel_format;
+
+   cursor_state->base.fb = intel_framebuffer_create(dev, 
&mode_cmd, cur_obj);
+   if (IS_ERR(cursor_state->base.fb)) {
+   
drm_gem_object_unreference_unlocked(&cur_obj->base);
+   goto gem_err;
+   }
+
+   if (i915_gem_obj_ggtt_pin(cur_obj, 0, 0) < 0) {
+   
drm_gem_object_unreference_unlocked(&cur_obj->base);
+   pinned = false;
+   goto cleanup;
+   }
+
+   

[Intel-gfx] [PATCH] drm/i915: Wait for PP cycle delay only if panel is in power off sequence

2015-12-09 Thread Shobhit Kumar
During resume, while turning the EDP panel power on, we need not wait
blindly for panel_power_cycle_delay. Check if panel power down sequence
in progress and then only wait. This improves our resume time significantly.

Signed-off-by: Shobhit Kumar 
---
 drivers/gpu/drm/i915/intel_dp.c | 17 -
 1 file changed, 16 insertions(+), 1 deletion(-)

diff --git a/drivers/gpu/drm/i915/intel_dp.c b/drivers/gpu/drm/i915/intel_dp.c
index f335c92..10ec669 100644
--- a/drivers/gpu/drm/i915/intel_dp.c
+++ b/drivers/gpu/drm/i915/intel_dp.c
@@ -617,6 +617,20 @@ static bool edp_have_panel_power(struct intel_dp *intel_dp)
return (I915_READ(_pp_stat_reg(intel_dp)) & PP_ON) != 0;
 }
 
+static bool edp_panel_off_seq(struct intel_dp *intel_dp)
+{
+   struct drm_device *dev = intel_dp_to_dev(intel_dp);
+   struct drm_i915_private *dev_priv = dev->dev_private;
+
+   lockdep_assert_held(&dev_priv->pps_mutex);
+
+   if (IS_VALLEYVIEW(dev) &&
+   intel_dp->pps_pipe == INVALID_PIPE)
+   return false;
+
+   return (I915_READ(_pp_stat_reg(intel_dp)) & PP_SEQUENCE_POWER_DOWN) != 
0;
+}
+
 static bool edp_have_panel_vdd(struct intel_dp *intel_dp)
 {
struct drm_device *dev = intel_dp_to_dev(intel_dp);
@@ -2025,7 +2039,8 @@ static void edp_panel_on(struct intel_dp *intel_dp)
 port_name(dp_to_dig_port(intel_dp)->port)))
return;
 
-   wait_panel_power_cycle(intel_dp);
+   if (edp_panel_off_seq(intel_dp))
+   wait_panel_power_cycle(intel_dp);
 
pp_ctrl_reg = _pp_ctrl_reg(intel_dp);
pp = ironlake_get_pp_control(intel_dp);
-- 
2.4.3

___
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/intel-gfx


Re: [Intel-gfx] [PATCH] drm/i915: Wait for PP cycle delay only if panel is in power off sequence

2015-12-09 Thread Shobhit Kumar
On Wed, Dec 9, 2015 at 7:27 PM, Ville Syrjälä
 wrote:
> On Wed, Dec 09, 2015 at 06:51:48PM +0530, Shobhit Kumar wrote:
>> During resume, while turning the EDP panel power on, we need not wait
>> blindly for panel_power_cycle_delay. Check if panel power down sequence
>> in progress and then only wait. This improves our resume time significantly.
>>
>> Signed-off-by: Shobhit Kumar 
>> ---
>>  drivers/gpu/drm/i915/intel_dp.c | 17 -
>>  1 file changed, 16 insertions(+), 1 deletion(-)
>>
>> diff --git a/drivers/gpu/drm/i915/intel_dp.c 
>> b/drivers/gpu/drm/i915/intel_dp.c
>> index f335c92..10ec669 100644
>> --- a/drivers/gpu/drm/i915/intel_dp.c
>> +++ b/drivers/gpu/drm/i915/intel_dp.c
>> @@ -617,6 +617,20 @@ static bool edp_have_panel_power(struct intel_dp 
>> *intel_dp)
>>   return (I915_READ(_pp_stat_reg(intel_dp)) & PP_ON) != 0;
>>  }
>>
>> +static bool edp_panel_off_seq(struct intel_dp *intel_dp)
>> +{
>> + struct drm_device *dev = intel_dp_to_dev(intel_dp);
>> + struct drm_i915_private *dev_priv = dev->dev_private;
>> +
>> + lockdep_assert_held(&dev_priv->pps_mutex);
>> +
>> + if (IS_VALLEYVIEW(dev) &&
>> + intel_dp->pps_pipe == INVALID_PIPE)
>> + return false;
>> +
>> + return (I915_READ(_pp_stat_reg(intel_dp)) & PP_SEQUENCE_POWER_DOWN) != 
>> 0;
>> +}
>
> This doens't make sense to me. The power down cycle may have
> completed just before, and so this would claim we don't have to
> wait for the power_cycle_delay.

Not sure I understand your concern correctly. You are right, power
down cycle may have completed just before and if it has then we don't
need to wait. But in case the power down cycle is in progress as per
internal state, then we need to wait for it to complete. This will
happen for example in non-suspend disable path and will be handled
correctly. In case of actual suspend/resume, this would have
successfully completed and will skip the wait as it is not needed
before enabling panel power.

>
>> +
>>  static bool edp_have_panel_vdd(struct intel_dp *intel_dp)
>>  {
>>   struct drm_device *dev = intel_dp_to_dev(intel_dp);
>> @@ -2025,7 +2039,8 @@ static void edp_panel_on(struct intel_dp *intel_dp)
>>port_name(dp_to_dig_port(intel_dp)->port)))
>>   return;
>>
>> - wait_panel_power_cycle(intel_dp);
>> + if (edp_panel_off_seq(intel_dp))
>> + wait_panel_power_cycle(intel_dp);
>>
>>   pp_ctrl_reg = _pp_ctrl_reg(intel_dp);
>>   pp = ironlake_get_pp_control(intel_dp);
>> --
>> 2.4.3
>
> --
> Ville Syrjälä
> Intel OTC
> ___
> Intel-gfx mailing list
> Intel-gfx@lists.freedesktop.org
> http://lists.freedesktop.org/mailman/listinfo/intel-gfx
___
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/intel-gfx


Re: [Intel-gfx] [PATCH] drm/i915: Wait for PP cycle delay only if panel is in power off sequence

2015-12-09 Thread Shobhit Kumar
On Wed, Dec 9, 2015 at 8:34 PM, Chris Wilson  wrote:
> On Wed, Dec 09, 2015 at 08:07:10PM +0530, Shobhit Kumar wrote:
>> On Wed, Dec 9, 2015 at 7:27 PM, Ville Syrjälä
>>  wrote:
>> > On Wed, Dec 09, 2015 at 06:51:48PM +0530, Shobhit Kumar wrote:
>> >> During resume, while turning the EDP panel power on, we need not wait
>> >> blindly for panel_power_cycle_delay. Check if panel power down sequence
>> >> in progress and then only wait. This improves our resume time 
>> >> significantly.
>> >>
>> >> Signed-off-by: Shobhit Kumar 
>> >> ---
>> >>  drivers/gpu/drm/i915/intel_dp.c | 17 -
>> >>  1 file changed, 16 insertions(+), 1 deletion(-)
>> >>
>> >> diff --git a/drivers/gpu/drm/i915/intel_dp.c 
>> >> b/drivers/gpu/drm/i915/intel_dp.c
>> >> index f335c92..10ec669 100644
>> >> --- a/drivers/gpu/drm/i915/intel_dp.c
>> >> +++ b/drivers/gpu/drm/i915/intel_dp.c
>> >> @@ -617,6 +617,20 @@ static bool edp_have_panel_power(struct intel_dp 
>> >> *intel_dp)
>> >>   return (I915_READ(_pp_stat_reg(intel_dp)) & PP_ON) != 0;
>> >>  }
>> >>
>> >> +static bool edp_panel_off_seq(struct intel_dp *intel_dp)
>> >> +{
>> >> + struct drm_device *dev = intel_dp_to_dev(intel_dp);
>> >> + struct drm_i915_private *dev_priv = dev->dev_private;
>> >> +
>> >> + lockdep_assert_held(&dev_priv->pps_mutex);
>> >> +
>> >> + if (IS_VALLEYVIEW(dev) &&
>> >> + intel_dp->pps_pipe == INVALID_PIPE)
>> >> + return false;
>> >> +
>> >> + return (I915_READ(_pp_stat_reg(intel_dp)) & PP_SEQUENCE_POWER_DOWN) 
>> >> != 0;
>> >> +}
>> >
>> > This doens't make sense to me. The power down cycle may have
>> > completed just before, and so this would claim we don't have to
>> > wait for the power_cycle_delay.
>>
>> Not sure I understand your concern correctly. You are right, power
>> down cycle may have completed just before and if it has then we don't
>> need to wait. But in case the power down cycle is in progress as per
>> internal state, then we need to wait for it to complete. This will
>> happen for example in non-suspend disable path and will be handled
>> correctly. In case of actual suspend/resume, this would have
>> successfully completed and will skip the wait as it is not needed
>> before enabling panel power.
>>
>> >
>> >> +
>> >>  static bool edp_have_panel_vdd(struct intel_dp *intel_dp)
>> >>  {
>> >>   struct drm_device *dev = intel_dp_to_dev(intel_dp);
>> >> @@ -2025,7 +2039,8 @@ static void edp_panel_on(struct intel_dp *intel_dp)
>> >>port_name(dp_to_dig_port(intel_dp)->port)))
>> >>   return;
>> >>
>> >> - wait_panel_power_cycle(intel_dp);
>> >> + if (edp_panel_off_seq(intel_dp))
>> >> + wait_panel_power_cycle(intel_dp);
>
> Looking in from the side, I have no idea what this is meant to do. At
> the very least you need your explanatory paragraph here which would
> include what exactly you are waiting for at the start of edp_panel_on
> (and please try and find a better name for edp_panel_off_seq()).

I will add a comment. Basically I am not additionally waiting, but
converting the wait which was already there to a conditional wait. The
edp_panel_off_seq, checks if panel power down sequence is in progress.
In that case we need to wait for the panel power cycle delay. If it is
not in that sequence, there is no need to wait. I will make an attempt
again on the naming in next patch update.

Regards
Shobhit

> -Chris
>
> --
> Chris Wilson, Intel Open Source Technology Centre
___
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/intel-gfx


Re: [Intel-gfx] [PATCH v5 45/46] drm: i915: switch to the atomic PWM API

2016-03-31 Thread Shobhit Kumar

On Thursday 31 March 2016 12:04 PM, Jani Nikula wrote:


[aggressively trimmed the recipient list, can't seem to be able to send
this otherwise]

On Wed, 30 Mar 2016, Boris Brezillon  wrote:

pwm_config/enable/disable() have been deprecated and should be replaced
by pwm_apply_state().

Signed-off-by: Boris Brezillon 


Reviewed-by: Jani Nikula 

Cc: Shobhit, any additional comments?


Looks good to me.

Reviewed-by: Shobhit Kumar 




---
  drivers/gpu/drm/i915/intel_panel.c | 39 +-
  1 file changed, 26 insertions(+), 13 deletions(-)

diff --git a/drivers/gpu/drm/i915/intel_panel.c 
b/drivers/gpu/drm/i915/intel_panel.c
index 21ee647..b86bd20 100644
--- a/drivers/gpu/drm/i915/intel_panel.c
+++ b/drivers/gpu/drm/i915/intel_panel.c
@@ -538,10 +538,10 @@ static u32 bxt_get_backlight(struct intel_connector 
*connector)
  static u32 pwm_get_backlight(struct intel_connector *connector)
  {
struct intel_panel *panel = &connector->panel;
-   int duty_ns;
+   struct pwm_state pstate;

-   duty_ns = pwm_get_duty_cycle(panel->backlight.pwm);
-   return DIV_ROUND_UP(duty_ns * 100, CRC_PMIC_PWM_PERIOD_NS);
+   pwm_get_state(panel->backlight.pwm, &pstate);
+   return DIV_ROUND_UP(pstate.duty_cycle * 100, CRC_PMIC_PWM_PERIOD_NS);
  }

  static u32 intel_panel_get_backlight(struct intel_connector *connector)
@@ -630,9 +630,12 @@ static void bxt_set_backlight(struct intel_connector 
*connector, u32 level)
  static void pwm_set_backlight(struct intel_connector *connector, u32 level)
  {
struct intel_panel *panel = &connector->panel;
-   int duty_ns = DIV_ROUND_UP(level * CRC_PMIC_PWM_PERIOD_NS, 100);
+   struct pwm_state pstate;

-   pwm_config(panel->backlight.pwm, duty_ns, CRC_PMIC_PWM_PERIOD_NS);
+   pwm_get_state(panel->backlight.pwm, &pstate);
+   pstate.duty_cycle = DIV_ROUND_UP(level * CRC_PMIC_PWM_PERIOD_NS, 100);
+   pstate.period = CRC_PMIC_PWM_PERIOD_NS;
+   pwm_apply_state(panel->backlight.pwm, &pstate);
  }

  static void
@@ -801,11 +804,15 @@ static void bxt_disable_backlight(struct intel_connector 
*connector)
  static void pwm_disable_backlight(struct intel_connector *connector)
  {
struct intel_panel *panel = &connector->panel;
+   struct pwm_state pstate;

/* Disable the backlight */
-   pwm_config(panel->backlight.pwm, 0, CRC_PMIC_PWM_PERIOD_NS);
+   pwm_get_state(panel->backlight.pwm, &pstate);
+   pstate.duty_cycle = 0;
+   pwm_apply_state(panel->backlight.pwm, &pstate);
usleep_range(2000, 3000);
-   pwm_disable(panel->backlight.pwm);
+   pstate.enabled = false;
+   pwm_apply_state(panel->backlight.pwm, &pstate);
  }

  void intel_panel_disable_backlight(struct intel_connector *connector)
@@ -1068,8 +1075,11 @@ static void bxt_enable_backlight(struct intel_connector 
*connector)
  static void pwm_enable_backlight(struct intel_connector *connector)
  {
struct intel_panel *panel = &connector->panel;
+   struct pwm_state pstate;

-   pwm_enable(panel->backlight.pwm);
+   pwm_get_state(panel->backlight.pwm, &pstate);
+   pstate.enabled = true;
+   pwm_apply_state(panel->backlight.pwm, &pstate);
intel_panel_actually_set_backlight(connector, panel->backlight.level);
  }

@@ -1630,6 +1640,7 @@ static int pwm_setup_backlight(struct intel_connector 
*connector,
  {
struct drm_device *dev = connector->base.dev;
struct intel_panel *panel = &connector->panel;
+   struct pwm_state pstate;
int retval;

/* Get the PWM chip for backlight control */
@@ -1640,8 +1651,10 @@ static int pwm_setup_backlight(struct intel_connector 
*connector,
return -ENODEV;
}

-   retval = pwm_config(panel->backlight.pwm, CRC_PMIC_PWM_PERIOD_NS,
-   CRC_PMIC_PWM_PERIOD_NS);
+   pwm_get_state(panel->backlight.pwm, &pstate);
+   pstate.period = CRC_PMIC_PWM_PERIOD_NS;
+   pstate.duty_cycle = CRC_PMIC_PWM_PERIOD_NS;
+   retval = pwm_apply_state(panel->backlight.pwm, &pstate);
if (retval < 0) {
DRM_ERROR("Failed to configure the pwm chip\n");
pwm_put(panel->backlight.pwm);
@@ -1651,9 +1664,9 @@ static int pwm_setup_backlight(struct intel_connector 
*connector,

panel->backlight.min = 0; /* 0% */
panel->backlight.max = 100; /* 100% */
-   panel->backlight.level = DIV_ROUND_UP(
-pwm_get_duty_cycle(panel->backlight.pwm) * 100,
-CRC_PMIC_PWM_PERIOD_NS);
+   pwm_get_state(panel->backlight.pwm, &pstate);
+   panel->backlight.level = DIV_ROUND_UP(pstate.duty_cycle * 100,
+ pstate.period);
panel->back

[Intel-gfx] [v2] drm/i915/skl: Init cdclk in the driver rather than relying on pre-os

2015-10-07 Thread Shobhit Kumar
Reuse what is programmed by pre-os, but in case there is no pre-os
initialization, init the cdclk with the max value by default untill
dynamic cdclk support comes.

v2: Check if BIOS programmed correctly rather than always calling init
- Do validation of programmed cdctl and what it is expected
- Only do slk_init_cdclk if validation failed else reuse BIOS
  programmed value

Cc: Imre Deak 
Cc: Ville Syrjälä 
Signed-off-by: Shobhit Kumar 
---
 drivers/gpu/drm/i915/intel_ddi.c | 18 -
 drivers/gpu/drm/i915/intel_display.c | 39 +++-
 2 files changed, 42 insertions(+), 15 deletions(-)

diff --git a/drivers/gpu/drm/i915/intel_ddi.c b/drivers/gpu/drm/i915/intel_ddi.c
index 2d3cc82..3ec5618 100644
--- a/drivers/gpu/drm/i915/intel_ddi.c
+++ b/drivers/gpu/drm/i915/intel_ddi.c
@@ -2946,11 +2946,19 @@ void intel_ddi_pll_init(struct drm_device *dev)
int cdclk_freq;
 
cdclk_freq = dev_priv->display.get_display_clock_speed(dev);
-   dev_priv->skl_boot_cdclk = cdclk_freq;
-   if (!(I915_READ(LCPLL1_CTL) & LCPLL_PLL_ENABLE))
-   DRM_ERROR("LCPLL1 is disabled\n");
-   else
-   intel_display_power_get(dev_priv, POWER_DOMAIN_PLLS);
+
+   /* Invalid CDCLK from BIOS ? */
+   if (cdclk_freq < 0) {
+   /* program to maximum cdclk till we have dynamic cdclk 
support */
+   dev_priv->skl_boot_cdclk = 675000;
+   skl_init_cdclk(dev_priv);
+   } else {
+   dev_priv->skl_boot_cdclk = cdclk_freq;
+   if (!(I915_READ(LCPLL1_CTL) & LCPLL_PLL_ENABLE))
+   DRM_ERROR("LCPLL1 is disabled\n");
+   else
+   intel_display_power_get(dev_priv, 
POWER_DOMAIN_PLLS);
+   }
} else if (IS_BROXTON(dev)) {
broxton_init_cdclk(dev);
broxton_ddi_phy_init(dev);
diff --git a/drivers/gpu/drm/i915/intel_display.c 
b/drivers/gpu/drm/i915/intel_display.c
index bbeb6d3..f734410 100644
--- a/drivers/gpu/drm/i915/intel_display.c
+++ b/drivers/gpu/drm/i915/intel_display.c
@@ -6634,12 +6634,15 @@ static int skylake_get_display_clock_speed(struct 
drm_device *dev)
uint32_t lcpll1 = I915_READ(LCPLL1_CTL);
uint32_t cdctl = I915_READ(CDCLK_CTL);
uint32_t linkrate;
+   int freq;
 
if (!(lcpll1 & LCPLL_PLL_ENABLE))
return 24000; /* 24MHz is the cd freq with NSSC ref */
 
-   if ((cdctl & CDCLK_FREQ_SEL_MASK) == CDCLK_FREQ_540)
-   return 54;
+   if ((cdctl & CDCLK_FREQ_SEL_MASK) == CDCLK_FREQ_540) {
+   freq = 54;
+   goto verify;
+   }
 
linkrate = (I915_READ(DPLL_CTRL1) &
DPLL_CTRL1_LINK_RATE_MASK(SKL_DPLL0)) >> 1;
@@ -6649,30 +6652,46 @@ static int skylake_get_display_clock_speed(struct 
drm_device *dev)
/* vco 8640 */
switch (cdctl & CDCLK_FREQ_SEL_MASK) {
case CDCLK_FREQ_450_432:
-   return 432000;
+   freq = 432000;
+   break;
case CDCLK_FREQ_337_308:
-   return 308570;
+   freq = 308570;
+   break;
case CDCLK_FREQ_675_617:
-   return 617140;
+   freq = 617140;
+   break;
default:
WARN(1, "Unknown cd freq selection\n");
+   return -EINVAL;
}
} else {
/* vco 8100 */
switch (cdctl & CDCLK_FREQ_SEL_MASK) {
case CDCLK_FREQ_450_432:
-   return 45;
+   freq = 45;
+   break;
case CDCLK_FREQ_337_308:
-   return 337500;
+   freq = 337500;
+   break;
case CDCLK_FREQ_675_617:
-   return 675000;
+   freq = 675000;
+   break;
default:
WARN(1, "Unknown cd freq selection\n");
+   return -EINVAL;
}
}
 
-   /* error case, do as if DPLL0 isn't enabled */
-   return 24000;
+verify:
+   /*
+* Noticed in some instances that the freq selection is correct but
+* decimal part is programmed wrong from BIOS where pre-os does not
+* enable display. Verify the same as well.
+*/
+   if (cdctl == ((cdctl & CDCLK_FREQ_SEL_MASK) | skl_cdclk_decimal(freq)))
+   return freq;
+   else
+

[Intel-gfx] [v3] drm/i915/skl: If needed sanitize bios programmed cdclk

2015-10-16 Thread Shobhit Kumar
Especially in cases where pre-os does not enable display, cdclk might
not be in sane state. During sanitization initialize cdclk with maximum
value till we get dynamic cdclk support.

v2: Check if BIOS programmed correctly rather than always calling init
- Do validation of programmed cdctl and what it is expected
- Only do slk_init_cdclk if validation failed else reuse BIOS
  programmed value

v3: Move the validation logic in a separate sanitize function (Ville)

Cc: Imre Deak 
Cc: Ville Syrjälä 
Signed-off-by: Shobhit Kumar 
---
 drivers/gpu/drm/i915/intel_ddi.c | 12 
 drivers/gpu/drm/i915/intel_display.c | 31 +++
 drivers/gpu/drm/i915/intel_drv.h |  1 +
 3 files changed, 40 insertions(+), 4 deletions(-)

diff --git a/drivers/gpu/drm/i915/intel_ddi.c b/drivers/gpu/drm/i915/intel_ddi.c
index b25e99a..86d43e6 100644
--- a/drivers/gpu/drm/i915/intel_ddi.c
+++ b/drivers/gpu/drm/i915/intel_ddi.c
@@ -2949,10 +2949,14 @@ void intel_ddi_pll_init(struct drm_device *dev)
 
cdclk_freq = dev_priv->display.get_display_clock_speed(dev);
dev_priv->skl_boot_cdclk = cdclk_freq;
-   if (!(I915_READ(LCPLL1_CTL) & LCPLL_PLL_ENABLE))
-   DRM_ERROR("LCPLL1 is disabled\n");
-   else
-   intel_display_power_get(dev_priv, POWER_DOMAIN_PLLS);
+   if (skl_sanitize_cdclk(dev_priv))
+   DRM_DEBUG_KMS("Sanitized cdclk programmed by pre-os\n");
+   else {
+   if (!(I915_READ(LCPLL1_CTL) & LCPLL_PLL_ENABLE))
+   DRM_ERROR("LCPLL1 is disabled\n");
+   else
+   intel_display_power_get(dev_priv, 
POWER_DOMAIN_PLLS);
+   }
} else if (IS_BROXTON(dev)) {
broxton_init_cdclk(dev);
broxton_ddi_phy_init(dev);
diff --git a/drivers/gpu/drm/i915/intel_display.c 
b/drivers/gpu/drm/i915/intel_display.c
index 5f37f84..98333d3 100644
--- a/drivers/gpu/drm/i915/intel_display.c
+++ b/drivers/gpu/drm/i915/intel_display.c
@@ -5784,6 +5784,37 @@ void skl_init_cdclk(struct drm_i915_private *dev_priv)
DRM_ERROR("DBuf power enable timeout\n");
 }
 
+int skl_sanitize_cdclk(struct drm_i915_private *dev_priv)
+{
+   uint32_t lcpll1 = I915_READ(LCPLL1_CTL);
+   uint32_t cdctl = I915_READ(CDCLK_CTL);
+   int freq = dev_priv->skl_boot_cdclk;
+
+   /* Is PLL enabled and locked ? */
+   if (!((lcpll1 & LCPLL_PLL_ENABLE) && (lcpll1 & LCPLL_PLL_LOCK)))
+   goto sanitize;
+
+   /* DPLL okay; verify the cdclock
+*
+* Noticed in some instances that the freq selection is correct but
+* decimal part is programmed wrong from BIOS where pre-os does not
+* enable display. Verify the same as well.
+*/
+   if (cdctl == ((cdctl & CDCLK_FREQ_SEL_MASK) | skl_cdclk_decimal(freq)))
+   /* All well; nothing to sanitize */
+   return false;
+sanitize:
+   /*
+* As of now initialize with max cdclk till
+* we get dynamic cdclk support
+* */
+   dev_priv->skl_boot_cdclk = 675000;
+   skl_init_cdclk(dev_priv);
+
+   /* we did have to sanitize */
+   return true;
+}
+
 /* Adjust CDclk dividers to allow high res or save power if possible */
 static void valleyview_set_cdclk(struct drm_device *dev, int cdclk)
 {
diff --git a/drivers/gpu/drm/i915/intel_drv.h b/drivers/gpu/drm/i915/intel_drv.h
index 0598932..ec10e6a 100644
--- a/drivers/gpu/drm/i915/intel_drv.h
+++ b/drivers/gpu/drm/i915/intel_drv.h
@@ -1152,6 +1152,7 @@ void broxton_ddi_phy_uninit(struct drm_device *dev);
 void bxt_enable_dc9(struct drm_i915_private *dev_priv);
 void bxt_disable_dc9(struct drm_i915_private *dev_priv);
 void skl_init_cdclk(struct drm_i915_private *dev_priv);
+int skl_sanitize_cdclk(struct drm_i915_private *dev_priv);
 void skl_uninit_cdclk(struct drm_i915_private *dev_priv);
 void intel_dp_get_m_n(struct intel_crtc *crtc,
  struct intel_crtc_state *pipe_config);
-- 
2.4.3

___
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/intel-gfx


[Intel-gfx] [v4] drm/i915/skl: If needed sanitize bios programmed cdclk

2015-10-20 Thread Shobhit Kumar
Especially in cases where pre-os does not enable display, cdclk might
not be in sane state. During sanitization initialize cdclk with maximum
value till we get dynamic cdclk support.

v2: Check if BIOS programmed correctly rather than always calling init
- Do validation of programmed cdctl and what it is expected
- Only do slk_init_cdclk if validation failed else reuse BIOS
  programmed value

v3: Move the validation logic in a separate sanitize function (Ville)

v4: No need to check LCPLL after sanitize and use max_cdclk_freq instead
of hardcoded value (Ville)

Cc: Imre Deak 
Cc: Ville Syrjälä 
Signed-off-by: Shobhit Kumar 
---
 drivers/gpu/drm/i915/intel_ddi.c |  4 ++--
 drivers/gpu/drm/i915/intel_display.c | 31 +++
 drivers/gpu/drm/i915/intel_drv.h |  1 +
 3 files changed, 34 insertions(+), 2 deletions(-)

diff --git a/drivers/gpu/drm/i915/intel_ddi.c b/drivers/gpu/drm/i915/intel_ddi.c
index b25e99a..824b863 100644
--- a/drivers/gpu/drm/i915/intel_ddi.c
+++ b/drivers/gpu/drm/i915/intel_ddi.c
@@ -2949,8 +2949,8 @@ void intel_ddi_pll_init(struct drm_device *dev)
 
cdclk_freq = dev_priv->display.get_display_clock_speed(dev);
dev_priv->skl_boot_cdclk = cdclk_freq;
-   if (!(I915_READ(LCPLL1_CTL) & LCPLL_PLL_ENABLE))
-   DRM_ERROR("LCPLL1 is disabled\n");
+   if (skl_sanitize_cdclk(dev_priv))
+   DRM_DEBUG_KMS("Sanitized cdclk programmed by pre-os\n");
else
intel_display_power_get(dev_priv, POWER_DOMAIN_PLLS);
} else if (IS_BROXTON(dev)) {
diff --git a/drivers/gpu/drm/i915/intel_display.c 
b/drivers/gpu/drm/i915/intel_display.c
index 5f37f84..4933b72 100644
--- a/drivers/gpu/drm/i915/intel_display.c
+++ b/drivers/gpu/drm/i915/intel_display.c
@@ -5784,6 +5784,37 @@ void skl_init_cdclk(struct drm_i915_private *dev_priv)
DRM_ERROR("DBuf power enable timeout\n");
 }
 
+int skl_sanitize_cdclk(struct drm_i915_private *dev_priv)
+{
+   uint32_t lcpll1 = I915_READ(LCPLL1_CTL);
+   uint32_t cdctl = I915_READ(CDCLK_CTL);
+   int freq = dev_priv->skl_boot_cdclk;
+
+   /* Is PLL enabled and locked ? */
+   if (!((lcpll1 & LCPLL_PLL_ENABLE) && (lcpll1 & LCPLL_PLL_LOCK)))
+   goto sanitize;
+
+   /* DPLL okay; verify the cdclock
+*
+* Noticed in some instances that the freq selection is correct but
+* decimal part is programmed wrong from BIOS where pre-os does not
+* enable display. Verify the same as well.
+*/
+   if (cdctl == ((cdctl & CDCLK_FREQ_SEL_MASK) | skl_cdclk_decimal(freq)))
+   /* All well; nothing to sanitize */
+   return false;
+sanitize:
+   /*
+* As of now initialize with max cdclk till
+* we get dynamic cdclk support
+* */
+   dev_priv->skl_boot_cdclk = dev_priv->max_cdclk_freq;
+   skl_init_cdclk(dev_priv);
+
+   /* we did have to sanitize */
+   return true;
+}
+
 /* Adjust CDclk dividers to allow high res or save power if possible */
 static void valleyview_set_cdclk(struct drm_device *dev, int cdclk)
 {
diff --git a/drivers/gpu/drm/i915/intel_drv.h b/drivers/gpu/drm/i915/intel_drv.h
index 0598932..ec10e6a 100644
--- a/drivers/gpu/drm/i915/intel_drv.h
+++ b/drivers/gpu/drm/i915/intel_drv.h
@@ -1152,6 +1152,7 @@ void broxton_ddi_phy_uninit(struct drm_device *dev);
 void bxt_enable_dc9(struct drm_i915_private *dev_priv);
 void bxt_disable_dc9(struct drm_i915_private *dev_priv);
 void skl_init_cdclk(struct drm_i915_private *dev_priv);
+int skl_sanitize_cdclk(struct drm_i915_private *dev_priv);
 void skl_uninit_cdclk(struct drm_i915_private *dev_priv);
 void intel_dp_get_m_n(struct intel_crtc *crtc,
  struct intel_crtc_state *pipe_config);
-- 
2.4.3

___
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/intel-gfx


[Intel-gfx] [PATCH] CDCLOCK Sanitization continued for SKL

2015-11-02 Thread Shobhit Kumar
The cdclock sanitization patch reviewed and merged at -
http://patchwork.freedesktop.org/patch/msgid/1445344992-14658-1-git-send-email-shobhit.ku...@intel.com

made the assumptions that DPLL should not be enabled when pre-os does not 
enable display and if it does then verify that the cdclock is corectly 
programmed as well. The BIOS was actually enabling DPLL as well while not 
following BSPEC sequence and writing cdclk register directly. I was working 
with BIOS team to correct this and found that due to a WA needed where audio 
codec will not be enumerated in OS if BIOS did not program the audio verbs 
which needed PG2 and DPLL enabling. More discussion revealed the following 
logic - 

1. BIOS puts max cdclk for the platform in CDCLK_CTL. VBIOS/GOP reads that 
value and then programs cdclk to desired value.
2. It also then sets SWF18 to indicate to the OS that it has enabled display. 
Used for fastmodeset actually in windows.
3. It also sets SWF06 with this max cdclock(from what bios programmed in 
CDCLK_CTL) for OS to know.

This patch uses point 2 above while sanitizing the cdclk. We can also update 
our logic for deciding max cdclock based on SWF06 if pre-os enables else 
directly from CDCLK_CTL (no pre-os display). That is not part of this patch.

Shobhit Kumar (1):
  drm/i915/skl: While sanitizing cdclock check the SWF18 as well

 drivers/gpu/drm/i915/i915_reg.h  | 3 +++
 drivers/gpu/drm/i915/intel_display.c | 8 
 2 files changed, 11 insertions(+)

-- 
2.4.3

___
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/intel-gfx


[Intel-gfx] [PATCH] drm/i915/skl: While sanitizing cdclock check the SWF18 as well

2015-11-02 Thread Shobhit Kumar
SWF18 is set if the display has been intialized by the pre-os. It
also gives what configuration is enabled on which pipe. The DPLL and
CDCLK verification checks can fail as the pre-os does initialize the
DPLL for Audio codec initialization. So fisrt check if SWF18 is set and
then follow through with other DPLL and CDCLK verification.

Cc: Ville Syrjälä 
Signed-off-by: Shobhit Kumar 
---
 drivers/gpu/drm/i915/i915_reg.h  | 3 +++
 drivers/gpu/drm/i915/intel_display.c | 8 
 2 files changed, 11 insertions(+)

diff --git a/drivers/gpu/drm/i915/i915_reg.h b/drivers/gpu/drm/i915/i915_reg.h
index 9ee9481..bd476ff 100644
--- a/drivers/gpu/drm/i915/i915_reg.h
+++ b/drivers/gpu/drm/i915/i915_reg.h
@@ -5006,6 +5006,9 @@ enum skl_disp_power_wells {
 #define SWF1(i)(dev_priv->info.display_mmio_offset + 0x71410 + (i) * 4)
 #define SWF3(i)(dev_priv->info.display_mmio_offset + 0x72414 + (i) * 4)
 
+/* VBIOS flag for display initialized status */
+#define GEN6_SWF18  (dev_priv->info.display_mmio_offset + 0x4F060)
+
 /* Pipe B */
 #define _PIPEBDSL  (dev_priv->info.display_mmio_offset + 0x71000)
 #define _PIPEBCONF (dev_priv->info.display_mmio_offset + 0x71008)
diff --git a/drivers/gpu/drm/i915/intel_display.c 
b/drivers/gpu/drm/i915/intel_display.c
index 103cacb..0ecb35c 100644
--- a/drivers/gpu/drm/i915/intel_display.c
+++ b/drivers/gpu/drm/i915/intel_display.c
@@ -5761,6 +5761,14 @@ int skl_sanitize_cdclk(struct drm_i915_private *dev_priv)
uint32_t cdctl = I915_READ(CDCLK_CTL);
int freq = dev_priv->skl_boot_cdclk;
 
+   /*
+* check if the pre-os intialized the display
+* There is SWF18 scratchpad register defined which is set by the
+* pre-os which can be used by the OS drivers to check the status
+*/
+   if ((I915_READ(GEN6_SWF18) & 0x00) == 0)
+   goto sanitize;
+
/* Is PLL enabled and locked ? */
if (!((lcpll1 & LCPLL_PLL_ENABLE) && (lcpll1 & LCPLL_PLL_LOCK)))
goto sanitize;
-- 
2.4.3

___
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/intel-gfx


[Intel-gfx] [v2] drm/i915/skl: While sanitizing cdclock check the SWF18 as well

2015-11-04 Thread Shobhit Kumar
SWF18 is set if the display has been intialized by the pre-os. It also
gives what configuration is enabled on which pipe. In skl_sanitize_cdclk,
the DPLL sanity check can pass even if GOP/VBIOS is not loaded as BIOS
enables DPLL for integrated audio codec related programming.
So fisrt check if SWF18 is set and then follow through with other DPLL
and CDCLK verification. If not set then for sure we need to sanitize the
cdclock.

v2: Update the commit message for clarity (Siva)

Cc: Ville Syrjälä 
Signed-off-by: Shobhit Kumar 
---
 drivers/gpu/drm/i915/i915_reg.h  | 3 +++
 drivers/gpu/drm/i915/intel_display.c | 8 
 2 files changed, 11 insertions(+)

diff --git a/drivers/gpu/drm/i915/i915_reg.h b/drivers/gpu/drm/i915/i915_reg.h
index 9ee9481..bd476ff 100644
--- a/drivers/gpu/drm/i915/i915_reg.h
+++ b/drivers/gpu/drm/i915/i915_reg.h
@@ -5006,6 +5006,9 @@ enum skl_disp_power_wells {
 #define SWF1(i)(dev_priv->info.display_mmio_offset + 0x71410 + (i) * 4)
 #define SWF3(i)(dev_priv->info.display_mmio_offset + 0x72414 + (i) * 4)
 
+/* VBIOS flag for display initialized status */
+#define GEN6_SWF18  (dev_priv->info.display_mmio_offset + 0x4F060)
+
 /* Pipe B */
 #define _PIPEBDSL  (dev_priv->info.display_mmio_offset + 0x71000)
 #define _PIPEBCONF (dev_priv->info.display_mmio_offset + 0x71008)
diff --git a/drivers/gpu/drm/i915/intel_display.c 
b/drivers/gpu/drm/i915/intel_display.c
index 103cacb..0ecb35c 100644
--- a/drivers/gpu/drm/i915/intel_display.c
+++ b/drivers/gpu/drm/i915/intel_display.c
@@ -5761,6 +5761,14 @@ int skl_sanitize_cdclk(struct drm_i915_private *dev_priv)
uint32_t cdctl = I915_READ(CDCLK_CTL);
int freq = dev_priv->skl_boot_cdclk;
 
+   /*
+* check if the pre-os intialized the display
+* There is SWF18 scratchpad register defined which is set by the
+* pre-os which can be used by the OS drivers to check the status
+*/
+   if ((I915_READ(GEN6_SWF18) & 0x00) == 0)
+   goto sanitize;
+
/* Is PLL enabled and locked ? */
if (!((lcpll1 & LCPLL_PLL_ENABLE) && (lcpll1 & LCPLL_PLL_LOCK)))
goto sanitize;
-- 
2.4.3

___
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/intel-gfx


[Intel-gfx] [v3] drm/i915/skl: While sanitizing cdclock check the SWF18 as well

2015-11-05 Thread Shobhit Kumar
SWF18 is set if the display has been intialized by the pre-os. It also
gives what configuration is enabled on which pipe. In skl_sanitize_cdclk,
the DPLL sanity check can pass even if GOP/VBIOS is not loaded as BIOS
enables DPLL for integrated audio codec related programming.
So fisrt check if SWF18 is set and then follow through with other DPLL
and CDCLK verification. If not set then for sure we need to sanitize the
cdclock.

v2: Update the commit message for clarity (Siva)
v3: Correct the mask to check for bits[23:0] instead of only bits[16:0].
Had missed checking for PIPE C altogether. Remaining are reserved (Siva)

Cc: Ville Syrjälä 
Signed-off-by: Shobhit Kumar 
---
 drivers/gpu/drm/i915/i915_reg.h  | 3 +++
 drivers/gpu/drm/i915/intel_display.c | 8 
 2 files changed, 11 insertions(+)

diff --git a/drivers/gpu/drm/i915/i915_reg.h b/drivers/gpu/drm/i915/i915_reg.h
index 9ee9481..bd476ff 100644
--- a/drivers/gpu/drm/i915/i915_reg.h
+++ b/drivers/gpu/drm/i915/i915_reg.h
@@ -5006,6 +5006,9 @@ enum skl_disp_power_wells {
 #define SWF1(i)(dev_priv->info.display_mmio_offset + 0x71410 + (i) * 4)
 #define SWF3(i)(dev_priv->info.display_mmio_offset + 0x72414 + (i) * 4)
 
+/* VBIOS flag for display initialized status */
+#define GEN6_SWF18  (dev_priv->info.display_mmio_offset + 0x4F060)
+
 /* Pipe B */
 #define _PIPEBDSL  (dev_priv->info.display_mmio_offset + 0x71000)
 #define _PIPEBCONF (dev_priv->info.display_mmio_offset + 0x71008)
diff --git a/drivers/gpu/drm/i915/intel_display.c 
b/drivers/gpu/drm/i915/intel_display.c
index 103cacb..81668b0 100644
--- a/drivers/gpu/drm/i915/intel_display.c
+++ b/drivers/gpu/drm/i915/intel_display.c
@@ -5761,6 +5761,14 @@ int skl_sanitize_cdclk(struct drm_i915_private *dev_priv)
uint32_t cdctl = I915_READ(CDCLK_CTL);
int freq = dev_priv->skl_boot_cdclk;
 
+   /*
+* check if the pre-os intialized the display
+* There is SWF18 scratchpad register defined which is set by the
+* pre-os which can be used by the OS drivers to check the status
+*/
+   if ((I915_READ(GEN6_SWF18) & 0x00FF) == 0)
+   goto sanitize;
+
/* Is PLL enabled and locked ? */
if (!((lcpll1 & LCPLL_PLL_ENABLE) && (lcpll1 & LCPLL_PLL_LOCK)))
goto sanitize;
-- 
2.4.3

___
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/intel-gfx


[Intel-gfx] [v4] drm/i915/skl: While sanitizing cdclock check the SWF18 as well

2015-11-05 Thread Shobhit Kumar
SWF18 is set if the display has been intialized by the pre-os. It also
gives what configuration is enabled on which pipe. In skl_sanitize_cdclk,
the DPLL sanity check can pass even if GOP/VBIOS is not loaded as BIOS
enables DPLL for integrated audio codec related programming.
So fisrt check if SWF18 is set and then follow through with other DPLL
and CDCLK verification. If not set then for sure we need to sanitize the
cdclock.

v2: Update the commit message for clarity (Siva)
v3: Correct the mask to check for bits[23:0] instead of only bits[16:0].
Had missed checking for PIPE C altogether. Remaining are reserved (Siva)
v4: Use ILK_SWF macro for SWF register definitions. Taken from Ville's patch
http://lists.freedesktop.org/archives/intel-gfx/2015-November/079480.html

Cc: Ville Syrjälä 
Signed-off-by: Shobhit Kumar 
---
 drivers/gpu/drm/i915/i915_reg.h  | 1 +
 drivers/gpu/drm/i915/intel_display.c | 8 
 2 files changed, 9 insertions(+)

diff --git a/drivers/gpu/drm/i915/i915_reg.h b/drivers/gpu/drm/i915/i915_reg.h
index 9ee9481..e8f1d42 100644
--- a/drivers/gpu/drm/i915/i915_reg.h
+++ b/drivers/gpu/drm/i915/i915_reg.h
@@ -5005,6 +5005,7 @@ enum skl_disp_power_wells {
 #define SWF0(i)(dev_priv->info.display_mmio_offset + 0x70410 + (i) * 4)
 #define SWF1(i)(dev_priv->info.display_mmio_offset + 0x71410 + (i) * 4)
 #define SWF3(i)(dev_priv->info.display_mmio_offset + 0x72414 + (i) * 4)
+#define SWF_ILK(i) (0x4F000 + (i) * 4)
 
 /* Pipe B */
 #define _PIPEBDSL  (dev_priv->info.display_mmio_offset + 0x71000)
diff --git a/drivers/gpu/drm/i915/intel_display.c 
b/drivers/gpu/drm/i915/intel_display.c
index 103cacb..512747a 100644
--- a/drivers/gpu/drm/i915/intel_display.c
+++ b/drivers/gpu/drm/i915/intel_display.c
@@ -5761,6 +5761,14 @@ int skl_sanitize_cdclk(struct drm_i915_private *dev_priv)
uint32_t cdctl = I915_READ(CDCLK_CTL);
int freq = dev_priv->skl_boot_cdclk;
 
+   /*
+* check if the pre-os intialized the display
+* There is SWF18 scratchpad register defined which is set by the
+* pre-os which can be used by the OS drivers to check the status
+*/
+   if ((I915_READ(SWF_ILK(0x18)) & 0x00FF) == 0)
+   goto sanitize;
+
/* Is PLL enabled and locked ? */
if (!((lcpll1 & LCPLL_PLL_ENABLE) && (lcpll1 & LCPLL_PLL_LOCK)))
goto sanitize;
-- 
2.4.3

___
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/intel-gfx


[Intel-gfx] [PATCH 1/3] drm/i915: Encapsulate the pwm_device in a pwm_info structure

2016-01-12 Thread Shobhit Kumar
pwm_info helps in encapsulating the PWM period_ns values and will form
basis of adding new pwm devices which can then be genrically used by
initializing proper pwm_info structure in the backlight setup call.

Cc: cbroo...@gmail.com
Cc: jani.nik...@linux.intel.com
Signed-off-by: Shobhit Kumar 
---
 drivers/gpu/drm/i915/intel_drv.h   |  8 ++-
 drivers/gpu/drm/i915/intel_panel.c | 45 --
 2 files changed, 35 insertions(+), 18 deletions(-)

diff --git a/drivers/gpu/drm/i915/intel_drv.h b/drivers/gpu/drm/i915/intel_drv.h
index bdfe403..6f96769 100644
--- a/drivers/gpu/drm/i915/intel_drv.h
+++ b/drivers/gpu/drm/i915/intel_drv.h
@@ -161,6 +161,12 @@ struct intel_encoder {
enum hpd_pin hpd_pin;
 };
 
+struct intel_pwm_info {
+   struct pwm_device *dev;
+   unsigned int period_ns;
+   char *name;
+};
+
 struct intel_panel {
struct drm_display_mode *fixed_mode;
struct drm_display_mode *downclock_mode;
@@ -179,7 +185,7 @@ struct intel_panel {
/* PWM chip */
bool util_pin_active_low;   /* bxt+ */
u8 controller;  /* bxt+ only */
-   struct pwm_device *pwm;
+   struct intel_pwm_info *pwm;
 
struct backlight_device *device;
 
diff --git a/drivers/gpu/drm/i915/intel_panel.c 
b/drivers/gpu/drm/i915/intel_panel.c
index 21ee647..9e24c59 100644
--- a/drivers/gpu/drm/i915/intel_panel.c
+++ b/drivers/gpu/drm/i915/intel_panel.c
@@ -37,6 +37,13 @@
 
 #define CRC_PMIC_PWM_PERIOD_NS 21333
 
+/* CRC PMIC based PWM Information */
+struct intel_pwm_info crc_pwm_info = {
+   .period_ns = CRC_PMIC_PWM_PERIOD_NS,
+   .name = "pwm_backlight",
+   .dev = NULL,
+};
+
 void
 intel_fixed_panel_mode(const struct drm_display_mode *fixed_mode,
   struct drm_display_mode *adjusted_mode)
@@ -538,10 +545,11 @@ static u32 bxt_get_backlight(struct intel_connector 
*connector)
 static u32 pwm_get_backlight(struct intel_connector *connector)
 {
struct intel_panel *panel = &connector->panel;
+   struct intel_pwm_info *pwm = panel->backlight.pwm;
int duty_ns;
 
-   duty_ns = pwm_get_duty_cycle(panel->backlight.pwm);
-   return DIV_ROUND_UP(duty_ns * 100, CRC_PMIC_PWM_PERIOD_NS);
+   duty_ns = pwm_get_duty_cycle(pwm->dev);
+   return DIV_ROUND_UP(duty_ns * 100, pwm->period_ns);
 }
 
 static u32 intel_panel_get_backlight(struct intel_connector *connector)
@@ -630,9 +638,10 @@ static void bxt_set_backlight(struct intel_connector 
*connector, u32 level)
 static void pwm_set_backlight(struct intel_connector *connector, u32 level)
 {
struct intel_panel *panel = &connector->panel;
-   int duty_ns = DIV_ROUND_UP(level * CRC_PMIC_PWM_PERIOD_NS, 100);
+   struct intel_pwm_info *pwm = panel->backlight.pwm;
+   int duty_ns = DIV_ROUND_UP(level * pwm->period_ns, 100);
 
-   pwm_config(panel->backlight.pwm, duty_ns, CRC_PMIC_PWM_PERIOD_NS);
+   pwm_config(pwm->dev, duty_ns, pwm->period_ns);
 }
 
 static void
@@ -801,11 +810,12 @@ static void bxt_disable_backlight(struct intel_connector 
*connector)
 static void pwm_disable_backlight(struct intel_connector *connector)
 {
struct intel_panel *panel = &connector->panel;
+   struct intel_pwm_info *pwm = panel->backlight.pwm;
 
/* Disable the backlight */
-   pwm_config(panel->backlight.pwm, 0, CRC_PMIC_PWM_PERIOD_NS);
+   pwm_config(pwm->dev, 0, pwm->period_ns);
usleep_range(2000, 3000);
-   pwm_disable(panel->backlight.pwm);
+   pwm_disable(pwm->dev);
 }
 
 void intel_panel_disable_backlight(struct intel_connector *connector)
@@ -1069,7 +1079,7 @@ static void pwm_enable_backlight(struct intel_connector 
*connector)
 {
struct intel_panel *panel = &connector->panel;
 
-   pwm_enable(panel->backlight.pwm);
+   pwm_enable(panel->backlight.pwm->dev);
intel_panel_actually_set_backlight(connector, panel->backlight.level);
 }
 
@@ -1630,21 +1640,21 @@ static int pwm_setup_backlight(struct intel_connector 
*connector,
 {
struct drm_device *dev = connector->base.dev;
struct intel_panel *panel = &connector->panel;
+   struct intel_pwm_info *pwm = &crc_pwm_info;
int retval;
 
/* Get the PWM chip for backlight control */
-   panel->backlight.pwm = pwm_get(dev->dev, "pwm_backlight");
-   if (IS_ERR(panel->backlight.pwm)) {
-   DRM_ERROR("Failed to own the pwm chip\n");
+   pwm->dev = pwm_get(dev->dev, pwm->name);
+   if (IS_ERR(pwm->dev)) {
+   DRM_ERROR("Failed to own the pwm chip: %s\n", pwm->name);
panel->backlight.pwm = NULL;
return -ENODEV;
}
 
-   retval = pwm_config(panel->backlight.pwm, C

[Intel-gfx] [PATCH 0/3] LPSS PWM support for devices that support it

2016-01-12 Thread Shobhit Kumar
Hi,
This is an untested attempt to enable LPSS PWM in the driver. As part
of this did some restructuring for encapsulating the pwm_info inside the
panel->backlight itself. This makes enabling LPSS PWM clean and simple.

Not sending yet to pwm mailing list as this is all untested. C.B. please
test the patches and see if they work at all for you. For testing Please
enable -

CONFIG_PWM_LPSS=y
CONFIG_PWM_LPSS_PLATFORM=y

Regards
Shobhit

Shobhit Kumar (3):
  drm/i915: Encapsulate the pwm_device in a pwm_info structure
  pwm: lpss: Add intel-gfx as consumer device in lookup table
  drm/i915: Add support for LPSS PWM on devices that support it

 drivers/gpu/drm/i915/intel_drv.h   |  8 +-
 drivers/gpu/drm/i915/intel_panel.c | 59 +++---
 drivers/pwm/pwm-lpss-platform.c|  8 ++
 3 files changed, 57 insertions(+), 18 deletions(-)

-- 
2.4.3

___
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/intel-gfx


[Intel-gfx] [PATCH 2/3] pwm: lpss: Add intel-gfx as consumer device in lookup table

2016-01-12 Thread Shobhit Kumar
Cc: cbroo...@gmail.com
Cc: jani.nik...@linux.intel.com
Signed-off-by: Shobhit Kumar 
---
 drivers/pwm/pwm-lpss-platform.c | 8 
 1 file changed, 8 insertions(+)

diff --git a/drivers/pwm/pwm-lpss-platform.c b/drivers/pwm/pwm-lpss-platform.c
index 54433fc..910bc14 100644
--- a/drivers/pwm/pwm-lpss-platform.c
+++ b/drivers/pwm/pwm-lpss-platform.c
@@ -18,6 +18,11 @@
 
 #include "pwm-lpss.h"
 
+/* PWM consumed by the Intel GFX */
+static struct pwm_lookup lpss_pwm_lookup[] = {
+   PWM_LOOKUP("pwm-lpss", 0, ":00:02.0", "pwm_lpss", 0, 
PWM_POLARITY_NORMAL),
+};
+
 static int pwm_lpss_probe_platform(struct platform_device *pdev)
 {
const struct pwm_lpss_boardinfo *info;
@@ -38,6 +43,9 @@ static int pwm_lpss_probe_platform(struct platform_device 
*pdev)
 
platform_set_drvdata(pdev, lpwm);
 
+   /* Register intel-gfx device as allowed consumer */
+   pwm_add_table(lpss_pwm_lookup, ARRAY_SIZE(lpss_pwm_lookup));
+
pm_runtime_set_active(&pdev->dev);
pm_runtime_enable(&pdev->dev);
 
-- 
2.4.3

___
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/intel-gfx


[Intel-gfx] [PATCH 3/3] drm/i915: Add support for LPSS PWM on devices that support it

2016-01-12 Thread Shobhit Kumar
Cc: cbroo...@gmail.com
Cc: jani.nik...@linux.intel.com
Signed-off-by: Shobhit Kumar 
---
 drivers/gpu/drm/i915/intel_panel.c | 16 +++-
 1 file changed, 15 insertions(+), 1 deletion(-)

diff --git a/drivers/gpu/drm/i915/intel_panel.c 
b/drivers/gpu/drm/i915/intel_panel.c
index 9e24c59..16473fa 100644
--- a/drivers/gpu/drm/i915/intel_panel.c
+++ b/drivers/gpu/drm/i915/intel_panel.c
@@ -36,6 +36,7 @@
 #include "intel_drv.h"
 
 #define CRC_PMIC_PWM_PERIOD_NS 21333
+#define LPSS_PWM_PERIOD_NS 10240
 
 /* CRC PMIC based PWM Information */
 struct intel_pwm_info crc_pwm_info = {
@@ -44,6 +45,13 @@ struct intel_pwm_info crc_pwm_info = {
.dev = NULL,
 };
 
+/* LPSS based PWM Information */
+struct intel_pwm_info lpss_pwm_info = {
+   .period_ns = LPSS_PWM_PERIOD_NS,
+   .name = "pwm_lpss",
+   .dev = NULL,
+};
+
 void
 intel_fixed_panel_mode(const struct drm_display_mode *fixed_mode,
   struct drm_display_mode *adjusted_mode)
@@ -1639,10 +1647,16 @@ static int pwm_setup_backlight(struct intel_connector 
*connector,
   enum pipe pipe)
 {
struct drm_device *dev = connector->base.dev;
+   struct drm_i915_private *dev_priv = to_i915(connector->base.dev);
struct intel_panel *panel = &connector->panel;
-   struct intel_pwm_info *pwm = &crc_pwm_info;
+   struct intel_pwm_info *pwm;
int retval;
 
+   if (dev_priv->vbt.dsi.config->pwm_blc == PPS_BLC_PMIC)
+   pwm = &crc_pwm_info;
+   else /* PPS_BLC_SOC */
+   pwm = &lpss_pwm_info;
+
/* Get the PWM chip for backlight control */
pwm->dev = pwm_get(dev->dev, pwm->name);
if (IS_ERR(pwm->dev)) {
-- 
2.4.3

___
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/intel-gfx


[Intel-gfx] [PATCH 0/7] Misc WM fixes and Arbitrated Display Bandwidth WA for SKL

2016-01-14 Thread Shobhit Kumar
Hi,
This series add a set of updates to the WM calculation and also enables
arbitrated display bandwidth based WA. Some of these patches do overlap
with Matts work but we wanted to send them out as we have them in our
internal testing for early review. Most likley some of them can be
superceded by patches from Matt, or can be re-used if deemed necessary.

Especially "drm/i915/skl+: Use fb size for relative data rate calculation"
this already addresses some of Ville's comment on similar patch from Matt.

Regards
Shobhit

Kumar, Mahesh (6):
  drm/i915/skl+: Use proper bytes_per_pixel during WM calculation
  drm/i915/skl+: Use fb size for relative data rate calculation
  drm/i915/skl+: calculate ddb minimum allocation
  drm/i915/skl+: calculate plane pixel rate.
  drm/i915/skl+: Use scaling amount for plane data rate calculation
  drm/i915/skl: WA for watermark calculation based on Arbitrated Display
    BW

Shobhit Kumar (1):
  drm/i915: Add support to parse DMI table and get platform memory info

 drivers/gpu/drm/i915/i915_dma.c  |  19 +++
 drivers/gpu/drm/i915/i915_drv.h  |  15 ++
 drivers/gpu/drm/i915/intel_drv.h |   2 +
 drivers/gpu/drm/i915/intel_pm.c  | 294 +--
 4 files changed, 316 insertions(+), 14 deletions(-)

-- 
2.4.3

___
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/intel-gfx


[Intel-gfx] [PATCH 2/7] drm/i915/skl+: Use fb size for relative data rate calculation

2016-01-14 Thread Shobhit Kumar
From: "Kumar, Mahesh" 

Use FB size for relative data rate calculation. don't always use
pipe source width & height.
adjust height & width according to rotation.

Signed-off-by: Kumar, Mahesh 
---
 drivers/gpu/drm/i915/intel_pm.c | 42 -
 1 file changed, 33 insertions(+), 9 deletions(-)

diff --git a/drivers/gpu/drm/i915/intel_pm.c b/drivers/gpu/drm/i915/intel_pm.c
index 68f21b9..d33c4ff 100644
--- a/drivers/gpu/drm/i915/intel_pm.c
+++ b/drivers/gpu/drm/i915/intel_pm.c
@@ -2928,24 +2928,33 @@ skl_plane_relative_data_rate(const struct 
intel_crtc_state *cstate,
 int y)
 {
struct intel_crtc *intel_crtc = to_intel_crtc(cstate->base.crtc);
+   struct intel_plane_state *intel_pstate = to_intel_plane_state(pstate);
struct drm_framebuffer *fb = pstate->fb;
+   uint32_t width = 0, height = 0;
+
+   if (drm_rect_width(&intel_pstate->src)) {
+   width = drm_rect_width(&intel_pstate->src) >> 16;
+   height = drm_rect_height(&intel_pstate->src) >> 16;
+   } else {
+   width = intel_crtc->config->pipe_src_w;
+   height = intel_crtc->config->pipe_src_h;
+   }
+
+   if (intel_rotation_90_or_270(pstate->rotation))
+   swap(width, height);
 
/* for planar format */
if (fb->pixel_format == DRM_FORMAT_NV12) {
if (y)  /* y-plane data rate */
-   return intel_crtc->config->pipe_src_w *
-   intel_crtc->config->pipe_src_h *
+   return width * height *
drm_format_plane_cpp(fb->pixel_format, 0);
else/* uv-plane data rate */
-   return (intel_crtc->config->pipe_src_w/2) *
-   (intel_crtc->config->pipe_src_h/2) *
+   return (width / 2) * (height / 2) *
drm_format_plane_cpp(fb->pixel_format, 1);
}
 
/* for packed formats */
-   return intel_crtc->config->pipe_src_w *
-   intel_crtc->config->pipe_src_h *
-   drm_format_plane_cpp(fb->pixel_format, 0);
+   return width * height * drm_format_plane_cpp(fb->pixel_format, 0);
 }
 
 /*
@@ -3181,10 +3190,25 @@ static bool skl_compute_plane_wm(const struct 
drm_i915_private *dev_priv,
uint32_t res_blocks, res_lines;
uint32_t selected_result;
uint8_t bytes_per_pixel;
+   struct intel_crtc *intel_crtc = to_intel_crtc(cstate->base.crtc);
+   struct intel_plane_state *intel_pstate = 
to_intel_plane_state(plane->state);
+   uint32_t width = 0, height = 0;
 
if (latency == 0 || !cstate->base.active || !fb)
return false;
 
+   if (drm_rect_width(&intel_pstate->src)) {
+   width = drm_rect_width(&intel_pstate->src) >> 16;
+   height = drm_rect_height(&intel_pstate->src) >> 16;
+   } else {
+   width = intel_crtc->config->pipe_src_w;
+   height = intel_crtc->config->pipe_src_h;
+   }
+
+   if (intel_rotation_90_or_270(plane->state->rotation))
+   swap(width, height);
+
+   /* for planar format */
bytes_per_pixel = (fb->pixel_format == DRM_FORMAT_NV12) ?
drm_format_plane_cpp(fb->pixel_format, 1) :
drm_format_plane_cpp(fb->pixel_format, 0);
@@ -3193,12 +3217,12 @@ static bool skl_compute_plane_wm(const struct 
drm_i915_private *dev_priv,
 latency);
method2 = skl_wm_method2(skl_pipe_pixel_rate(cstate),
 cstate->base.adjusted_mode.crtc_htotal,
-cstate->pipe_src_w,
+width,
 bytes_per_pixel,
 fb->modifier[0],
 latency);
 
-   plane_bytes_per_line = cstate->pipe_src_w * bytes_per_pixel;
+   plane_bytes_per_line = width * bytes_per_pixel;
plane_blocks_per_line = DIV_ROUND_UP(plane_bytes_per_line, 512);
 
if (fb->modifier[0] == I915_FORMAT_MOD_Y_TILED ||
-- 
2.4.3

___
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/intel-gfx


[Intel-gfx] [PATCH 3/7] drm/i915/skl+: calculate ddb minimum allocation

2016-01-14 Thread Shobhit Kumar
From: "Kumar, Mahesh" 

don't always use 8 ddb as minimum, instead calculate using proper
algorithm.

Signed-off-by: Kumar, Mahesh 
---
 drivers/gpu/drm/i915/intel_pm.c | 57 +++--
 1 file changed, 55 insertions(+), 2 deletions(-)

diff --git a/drivers/gpu/drm/i915/intel_pm.c b/drivers/gpu/drm/i915/intel_pm.c
index d33c4ff..64b39ec 100644
--- a/drivers/gpu/drm/i915/intel_pm.c
+++ b/drivers/gpu/drm/i915/intel_pm.c
@@ -2994,6 +2994,59 @@ skl_get_total_relative_data_rate(const struct 
intel_crtc_state *cstate)
return total_data_rate;
 }
 
+static uint16_t
+skl_ddb_min_alloc(const struct intel_crtc *crtc,
+   const struct drm_plane *plane, int y)
+{
+   struct drm_framebuffer *fb = plane->state->fb;
+   struct intel_plane_state *pstate = to_intel_plane_state(plane->state);
+   uint16_t min_alloc;
+   uint32_t src_w, src_h;
+
+   /* For packed formats, no y-plane, return 0 */
+   if (y && !(fb->pixel_format == DRM_FORMAT_NV12))
+   return 0;
+
+   if (drm_rect_width(&pstate->src)) {
+   src_w = drm_rect_width(&pstate->src) >> 16;
+   src_h = drm_rect_height(&pstate->src) >> 16;
+   } else {
+   src_w = crtc->config->pipe_src_w;
+   src_h = crtc->config->pipe_src_h;
+   }
+
+   if (intel_rotation_90_or_270(plane->state->rotation))
+   swap(src_w, src_h);
+
+   if (fb->modifier[0] == I915_FORMAT_MOD_Y_TILED ||
+   fb->modifier[0] == I915_FORMAT_MOD_Yf_TILED) {
+   uint32_t min_scanlines = 8;
+   uint8_t bytes_per_pixel =
+   y ? drm_format_plane_cpp(fb->pixel_format, 1) :
+   drm_format_plane_cpp(fb->pixel_format, 0);
+
+   if (intel_rotation_90_or_270(plane->state->rotation)) {
+   switch (bytes_per_pixel) {
+   case 1:
+   min_scanlines = 32;
+   break;
+   case 2:
+   min_scanlines = 16;
+   break;
+   case 8:
+   WARN(1, "Unsupported pixel depth for rotation");
+   }
+   }
+   min_alloc = DIV_ROUND_UP((4 * src_w / (y ? 1 : 2) *
+   bytes_per_pixel), 512) * min_scanlines/4 + 3;
+   } else {
+   min_alloc = 8;
+   }
+
+   return min_alloc;
+}
+
+
 static void
 skl_allocate_pipe_ddb(struct intel_crtc_state *cstate,
  struct skl_ddb_allocation *ddb /* out */)
@@ -3038,9 +3091,9 @@ skl_allocate_pipe_ddb(struct intel_crtc_state *cstate,
if (plane->type == DRM_PLANE_TYPE_CURSOR)
continue;
 
-   minimum[id] = 8;
+   minimum[id] = skl_ddb_min_alloc(intel_crtc, plane, 0);
alloc_size -= minimum[id];
-   y_minimum[id] = (fb->pixel_format == DRM_FORMAT_NV12) ? 8 : 0;
+   y_minimum[id] = skl_ddb_min_alloc(intel_crtc, plane, 1);
alloc_size -= y_minimum[id];
}
 
-- 
2.4.3

___
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/intel-gfx


[Intel-gfx] [PATCH 7/7] drm/i915/skl: WA for watermark calculation based on Arbitrated Display BW

2016-01-14 Thread Shobhit Kumar
From: "Kumar, Mahesh" 

 If the arbitary display bandwidth is > 60% of memory bandwith, for
 x-tile we should increase latency at all levels by 15us.

 If the arbitary dsplay bandwidth is greater than 20% of memory bandwith
 in case of y-tile  being enabled, double the scan lines

v2: Update the commit message to explain the WA (shobhit)

Signed-off-by: Shobhit Kumar 
Signed-off-by: Kumar, Mahesh 
---
 drivers/gpu/drm/i915/i915_drv.h |  9 +
 drivers/gpu/drm/i915/intel_pm.c | 86 +
 2 files changed, 95 insertions(+)

diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h
index f588993..3c914a6 100644
--- a/drivers/gpu/drm/i915/i915_drv.h
+++ b/drivers/gpu/drm/i915/i915_drv.h
@@ -1620,6 +1620,12 @@ enum intel_pipe_crc_source {
INTEL_PIPE_CRC_SOURCE_MAX,
 };
 
+enum watermark_memory_wa {
+   WATERMARK_WA_NONE,
+   WATERMARK_WA_X_TILED,
+   WATERMARK_WA_Y_TILED,
+};
+
 struct intel_pipe_crc_entry {
uint32_t frame;
uint32_t crc[5];
@@ -1915,6 +1921,9 @@ struct drm_i915_private {
/* Committed wm config */
struct intel_wm_config config;
 
+   /* This stores if WaterMark memory workaround is needed */
+   enum watermark_memory_wa mem_wa;
+
/*
 * The skl_wm_values structure is a bit too big for stack
 * allocation, so we keep the staging struct where we store
diff --git a/drivers/gpu/drm/i915/intel_pm.c b/drivers/gpu/drm/i915/intel_pm.c
index dc08494..fb59f4e 100644
--- a/drivers/gpu/drm/i915/intel_pm.c
+++ b/drivers/gpu/drm/i915/intel_pm.c
@@ -3304,6 +3304,11 @@ static bool skl_compute_plane_wm(const struct 
drm_i915_private *dev_priv,
if (latency == 0 || !cstate->base.active || !fb)
return false;
 
+   if (dev_priv->wm.mem_wa != WATERMARK_WA_NONE) {
+   if (fb->modifier[0] == I915_FORMAT_MOD_X_TILED)
+   latency += 15;
+   }
+
if (drm_rect_width(&intel_pstate->src)) {
width = drm_rect_width(&intel_pstate->src) >> 16;
height = drm_rect_height(&intel_pstate->src) >> 16;
@@ -3352,6 +3357,9 @@ static bool skl_compute_plane_wm(const struct 
drm_i915_private *dev_priv,
WARN(1, "Unsupported pixel depth for rotation");
}
}
+   if (dev_priv->wm.mem_wa == WATERMARK_WA_Y_TILED)
+   min_scanlines *= 2;
+
y_tile_minimum = plane_blocks_per_line * min_scanlines;
selected_result = max(method2, y_tile_minimum);
} else {
@@ -3803,6 +3811,83 @@ static void skl_set_plane_pixel_rate(struct drm_crtc 
*crtc)
 
 }
 
+static void
+skl_set_display_memory_wa(struct drm_device *dev)
+{
+   struct drm_i915_private *dev_priv = dev->dev_private;
+   struct intel_crtc *intel_crtc = NULL;
+   struct intel_plane *intel_plane = NULL;
+   uint32_t num_active_crtc = 0;
+   uint64_t max_pixel_rate_pipe = 0;
+   uint64_t display_bw = 0, available_bw = 0;
+   bool y_tile_enabled = false;
+   int memory_portion = 0;
+
+   for_each_intel_crtc(dev, intel_crtc) {
+   uint64_t max_pixel_rate_plane = 0;
+   uint64_t pipe_bw;
+   uint32_t num_active_plane = 0;
+   const struct intel_crtc_state *cstate = NULL;
+
+   if (!intel_crtc->active)
+   continue;
+   cstate = to_intel_crtc_state(intel_crtc->base.state);
+   num_active_crtc++;
+
+   for_each_intel_plane_on_crtc(dev, intel_crtc, intel_plane) {
+   struct drm_plane *plane = &intel_plane->base;
+   struct drm_framebuffer *fb = plane->state->fb;
+   uint64_t plane_bw, interm_bw = 1000;
+
+   if (fb == NULL)
+   continue;
+   if (plane->type == DRM_PLANE_TYPE_CURSOR)
+   continue;
+   num_active_plane++;
+
+   if (fb->modifier[0] == I915_FORMAT_MOD_Y_TILED)
+   y_tile_enabled = true;
+
+   /*
+* planeBW = pixel_rate(MHz) * BPP * plane downscale
+*  amount * pipe downscale amount;
+*
+* skl_pipe_pixel_rate return adjusted value according
+* to downscaling  amount
+* pixel rate is in KHz & downscale factor is multiplied
+* by 1000, so devide by 1000*1000
+*/
+   interm_bw = skl_pipe_pixel_rate(cstate) *
+   drm_format_pla

[Intel-gfx] [PATCH 1/7] drm/i915/skl+: Use proper bytes_per_pixel during WM calculation

2016-01-14 Thread Shobhit Kumar
From: "Kumar, Mahesh" 

Don't always use bytes_per_pixel using y_plane=0, instead use it
according to pixel format. If NV12 use y_plane eqal to 1

Signed-off-by: Kumar, Mahesh 
---
 drivers/gpu/drm/i915/intel_pm.c | 4 +++-
 1 file changed, 3 insertions(+), 1 deletion(-)

diff --git a/drivers/gpu/drm/i915/intel_pm.c b/drivers/gpu/drm/i915/intel_pm.c
index 9df9e9a..68f21b9 100644
--- a/drivers/gpu/drm/i915/intel_pm.c
+++ b/drivers/gpu/drm/i915/intel_pm.c
@@ -3185,7 +3185,9 @@ static bool skl_compute_plane_wm(const struct 
drm_i915_private *dev_priv,
if (latency == 0 || !cstate->base.active || !fb)
return false;
 
-   bytes_per_pixel = drm_format_plane_cpp(fb->pixel_format, 0);
+   bytes_per_pixel = (fb->pixel_format == DRM_FORMAT_NV12) ?
+   drm_format_plane_cpp(fb->pixel_format, 1) :
+   drm_format_plane_cpp(fb->pixel_format, 0);
method1 = skl_wm_method1(skl_pipe_pixel_rate(cstate),
 bytes_per_pixel,
 latency);
-- 
2.4.3

___
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/intel-gfx


[Intel-gfx] [PATCH 6/7] drm/i915: Add support to parse DMI table and get platform memory info

2016-01-14 Thread Shobhit Kumar
This is needed for WM computation workaround for arbitrated display
bandwidth.

Signed-off-by: Shobhit Kumar 
---
 drivers/gpu/drm/i915/i915_dma.c | 19 +++
 drivers/gpu/drm/i915/i915_drv.h |  6 ++
 2 files changed, 25 insertions(+)

diff --git a/drivers/gpu/drm/i915/i915_dma.c b/drivers/gpu/drm/i915/i915_dma.c
index a0f5659..03c3131 100644
--- a/drivers/gpu/drm/i915/i915_dma.c
+++ b/drivers/gpu/drm/i915/i915_dma.c
@@ -49,6 +49,7 @@
 #include 
 #include 
 #include 
+#include 
 
 
 static int i915_getparam(struct drm_device *dev, void *data,
@@ -855,6 +856,21 @@ static void intel_init_dpio(struct drm_i915_private 
*dev_priv)
}
 }
 
+static void dmi_decode_memory_info(const struct dmi_header *hdr, void *priv)
+{
+   struct drm_i915_private *dev_priv = (struct drm_i915_private *) priv;
+   const u8 *data = (const u8 *) hdr;
+
+   if (hdr->type == 17 && hdr->length > 0x17) {
+
+   /* Found a memory channel */
+   dev_priv->dmi.mem_channel++;
+
+   /* Get the speed */
+   dev_priv->dmi.mem_speed = (uint16_t) (*((uint16_t *)(data + 
0x15)));
+   }
+}
+
 /**
  * i915_driver_load - setup chip and create an initial config
  * @dev: DRM device
@@ -882,6 +898,9 @@ int i915_driver_load(struct drm_device *dev, unsigned long 
flags)
dev->dev_private = dev_priv;
dev_priv->dev = dev;
 
+   /* walk the dmi device table for getting platform memory information */
+   dmi_walk(dmi_decode_memory_info, (void *) dev_priv);
+
/* Setup the write-once "constant" device info */
device_info = (struct intel_device_info *)&dev_priv->info;
memcpy(device_info, info, sizeof(dev_priv->info));
diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h
index 104bd18..f588993 100644
--- a/drivers/gpu/drm/i915/i915_drv.h
+++ b/drivers/gpu/drm/i915/i915_drv.h
@@ -1962,6 +1962,12 @@ struct drm_i915_private {
 * NOTE: This is the dri1/ums dungeon, don't add stuff here. Your patch
 * will be rejected. Instead look for a better place.
 */
+
+   /* DMI data for memory bandwidth calculation */
+   struct {
+   uint16_t mem_channel;
+   uint16_t mem_speed;
+   } dmi;
 };
 
 static inline struct drm_i915_private *to_i915(const struct drm_device *dev)
-- 
2.4.3

___
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/intel-gfx


[Intel-gfx] [PATCH 4/7] drm/i915/skl+: calculate plane pixel rate.

2016-01-14 Thread Shobhit Kumar
From: "Kumar, Mahesh" 

Don't use pipe pixel rate for plane pixel rate.
Calculate plane pixel according to formula

adjusted plane_pixel_rate = adjusted pipe_pixel_rate * downscale ammount

downscale amount = max[1, src_h/dst_h] * max[1, src_w/dst_w]
if 90/270 rotation use rotated width & height

Signed-off-by: Kumar, Mahesh 
---
 drivers/gpu/drm/i915/intel_drv.h |  2 +
 drivers/gpu/drm/i915/intel_pm.c  | 95 +++-
 2 files changed, 95 insertions(+), 2 deletions(-)

diff --git a/drivers/gpu/drm/i915/intel_drv.h b/drivers/gpu/drm/i915/intel_drv.h
index 059b46e..49f237e 100644
--- a/drivers/gpu/drm/i915/intel_drv.h
+++ b/drivers/gpu/drm/i915/intel_drv.h
@@ -661,6 +661,8 @@ struct intel_plane_wm_parameters {
u64 tiling;
unsigned int rotation;
uint16_t fifo_size;
+/* Stores the adjusted plane pixel rate for WM calculation */
+   uint32_t plane_pixel_rate;
 };
 
 struct intel_plane {
diff --git a/drivers/gpu/drm/i915/intel_pm.c b/drivers/gpu/drm/i915/intel_pm.c
index 64b39ec..ffcc56a 100644
--- a/drivers/gpu/drm/i915/intel_pm.c
+++ b/drivers/gpu/drm/i915/intel_pm.c
@@ -2841,6 +2841,54 @@ skl_wm_plane_id(const struct intel_plane *plane)
}
 }
 
+/*
+ * This function takes drm_plane_state as input
+ * and decides the downscale amount according to the formula
+ *
+ * downscale amount = Max[1, Horizontal source size / Horizontal dest size]
+ *
+ * Return value is multiplied by 1000 to retain fractional part
+ * Caller should take care of dividing & Rounding off the value
+ */
+static uint32_t
+skl_plane_downscale_amount(const struct intel_plane *intel_plane)
+{
+   struct drm_plane_state *pstate = intel_plane->base.state;
+   struct intel_crtc *crtc = to_intel_crtc(pstate->crtc);
+   struct intel_plane_state *intel_pstate = to_intel_plane_state(pstate);
+   uint32_t downscale_h, downscale_w;
+   uint32_t src_w, src_h, dst_w, dst_h, tmp;
+
+   if (drm_rect_width(&intel_pstate->src)) {
+   src_w = drm_rect_width(&intel_pstate->src) >> 16;
+   src_h = drm_rect_height(&intel_pstate->src) >> 16;
+   } else {
+   src_w = crtc->config->pipe_src_w;
+   src_h = crtc->config->pipe_src_h;
+   }
+
+   dst_w = drm_rect_width(&intel_pstate->dst);
+   dst_h = drm_rect_height(&intel_pstate->dst);
+
+   if (intel_rotation_90_or_270(pstate->rotation))
+   swap(dst_w, dst_h);
+
+   /* If destination height & wight are zero return amount as unity */
+   if (dst_w == 0 || dst_h == 0)
+   return 1000;
+
+   /* Multiply by 1000 for precision */
+   tmp = (1000 * src_h) / dst_h;
+   downscale_h = max_t(uint32_t, 1000, tmp);
+
+   tmp = (1000 * src_w) / dst_w;
+   downscale_w = max_t(uint32_t, 1000, tmp);
+
+   /* Reducing precision to 3 decimal places */
+   return DIV_ROUND_UP(downscale_h * downscale_w, 1000);
+}
+
+
 static void
 skl_ddb_get_pipe_allocation_limits(struct drm_device *dev,
   const struct intel_crtc_state *cstate,
@@ -3265,10 +3313,10 @@ static bool skl_compute_plane_wm(const struct 
drm_i915_private *dev_priv,
bytes_per_pixel = (fb->pixel_format == DRM_FORMAT_NV12) ?
drm_format_plane_cpp(fb->pixel_format, 1) :
drm_format_plane_cpp(fb->pixel_format, 0);
-   method1 = skl_wm_method1(skl_pipe_pixel_rate(cstate),
+   method1 = skl_wm_method1(intel_plane->wm.plane_pixel_rate,
 bytes_per_pixel,
 latency);
-   method2 = skl_wm_method2(skl_pipe_pixel_rate(cstate),
+   method2 = skl_wm_method2(intel_plane->wm.plane_pixel_rate,
 cstate->base.adjusted_mode.crtc_htotal,
 width,
 bytes_per_pixel,
@@ -3709,6 +3757,46 @@ static void skl_update_other_pipe_wm(struct drm_device 
*dev,
}
 }
 
+static uint32_t
+skl_plane_pixel_rate(struct intel_crtc_state *cstate, struct intel_plane 
*plane)
+{
+   uint32_t adjusted_pixel_rate;
+   uint32_t downscale_amount;
+
+   /*
+* adjusted plane pixel rate = adjusted pipe pixel rate
+* Plane pixel rate = adjusted plane pixel rate * plane down scale
+* amount
+*/
+   adjusted_pixel_rate = skl_pipe_pixel_rate(cstate);
+   downscale_amount = skl_plane_downscale_amount(plane);
+
+   return DIV_ROUND_UP(adjusted_pixel_rate * downscale_amount,
+   1000);
+}
+
+static void skl_set_plane_pixel_rate(struct drm_crtc *crtc)
+{
+   struct intel_crtc *intel_crtc = to_intel_crtc(crtc);
+   struct intel_crtc_state *cstate = to_intel_crtc_state(crtc->state);
+   struct intel_plane *intel_plane = NULL;
+   struct drm_device *dev = crtc->dev;
+
+   if (!intel_crtc->active)
+   return;
+   for_each_inte

[Intel-gfx] [PATCH 5/7] drm/i915/skl+: Use scaling amount for plane data rate calculation

2016-01-14 Thread Shobhit Kumar
From: "Kumar, Mahesh" 

Signed-off-by: Kumar, Mahesh 
---
 drivers/gpu/drm/i915/intel_pm.c | 12 +---
 1 file changed, 9 insertions(+), 3 deletions(-)

diff --git a/drivers/gpu/drm/i915/intel_pm.c b/drivers/gpu/drm/i915/intel_pm.c
index ffcc56a..dc08494 100644
--- a/drivers/gpu/drm/i915/intel_pm.c
+++ b/drivers/gpu/drm/i915/intel_pm.c
@@ -2978,6 +2978,8 @@ skl_plane_relative_data_rate(const struct 
intel_crtc_state *cstate,
struct intel_crtc *intel_crtc = to_intel_crtc(cstate->base.crtc);
struct intel_plane_state *intel_pstate = to_intel_plane_state(pstate);
struct drm_framebuffer *fb = pstate->fb;
+   struct intel_plane *intel_plane = to_intel_plane(pstate->plane);
+   uint32_t down_scale_amount, data_rate;
uint32_t width = 0, height = 0;
 
if (drm_rect_width(&intel_pstate->src)) {
@@ -2994,15 +2996,19 @@ skl_plane_relative_data_rate(const struct 
intel_crtc_state *cstate,
/* for planar format */
if (fb->pixel_format == DRM_FORMAT_NV12) {
if (y)  /* y-plane data rate */
-   return width * height *
+   data_rate = width * height *
drm_format_plane_cpp(fb->pixel_format, 0);
else/* uv-plane data rate */
-   return (width / 2) * (height / 2) *
+   data_rate = (width / 2) * (height / 2) *
drm_format_plane_cpp(fb->pixel_format, 1);
}
 
/* for packed formats */
-   return width * height * drm_format_plane_cpp(fb->pixel_format, 0);
+   data_rate = width * height * drm_format_plane_cpp(fb->pixel_format, 0);
+   down_scale_amount = skl_plane_downscale_amount(intel_plane);
+
+   return DIV_ROUND_UP((data_rate * down_scale_amount), 1000);
+
 }
 
 /*
-- 
2.4.3

___
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/intel-gfx


[Intel-gfx] [PATCH] drm/i915: Retry few time if gpiod_get fails during intel_dsi_init

2016-01-19 Thread Shobhit Kumar
INTEL_SOC_PMIC is loading later than I915 failing the gpiod_get and
pwm_get calls in i915. Add a retry to give time for the INTEL_SOC_PMIC
to load. This was fine till now but broke in latest kernel. Maybe load
time for the INTEL_SOC_PMIC has increased.

Since the lookup tables for GPIO (panel enable) and PWM both are
exported by same intel_soc_pmic driver, just retrying for the driver to
load in intel_dsi_init is sufficient. By the time we come to
setup_backlight, pwm would have been exported as well.

Signed-off-by: Shobhit Kumar 
---
 drivers/gpu/drm/i915/intel_dsi.c | 6 +-
 1 file changed, 5 insertions(+), 1 deletion(-)

diff --git a/drivers/gpu/drm/i915/intel_dsi.c b/drivers/gpu/drm/i915/intel_dsi.c
index 91cef35..e309ef6 100644
--- a/drivers/gpu/drm/i915/intel_dsi.c
+++ b/drivers/gpu/drm/i915/intel_dsi.c
@@ -1192,10 +1192,14 @@ void intel_dsi_init(struct drm_device *dev)
 * Panel control.
 */
if (dev_priv->vbt.dsi.config->pwm_blc == PPS_BLC_PMIC) {
+   int retry = 4;
+   do {
intel_dsi->gpio_panel =
gpiod_get(dev->dev, "panel", GPIOD_OUT_HIGH);
+   msleep(50);
+   } while (IS_ERR(intel_dsi->gpio_panel) && --retry);
 
-   if (IS_ERR(intel_dsi->gpio_panel)) {
+   if (!retry) {
DRM_ERROR("Failed to own gpio for panel control\n");
intel_dsi->gpio_panel = NULL;
}
-- 
1.9.1

___
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/intel-gfx


Re: [Intel-gfx] [PATCH 0/7] Misc WM fixes and Arbitrated Display Bandwidth WA for SKL

2016-01-24 Thread Shobhit Kumar
On Fri, Jan 15, 2016 at 10:32 AM, Kumar, Shobhit <
shobhit.ku...@linux.intel.com> wrote:

> On 01/15/2016 07:18 AM, Matt Roper wrote:
>
>> On Thu, Jan 14, 2016 at 05:32:41PM +0530, Shobhit Kumar wrote:
>>
>>> Hi,
>>> This series add a set of updates to the WM calculation and also enables
>>> arbitrated display bandwidth based WA. Some of these patches do overlap
>>> with Matts work but we wanted to send them out as we have them in our
>>> internal testing for early review. Most likley some of them can be
>>> superceded by patches from Matt, or can be re-used if deemed necessary.
>>>
>>
>> I've left some feedback on your patches, but it was all pretty minor;
>> they look pretty good overall.  So I think we should polish up this set
>> and merge it; I've got more SKL WM work coming (more atomic-y watermark
>> calculation and programming) but I'll hold off on that until your series
>> lands so that I don't cause too much thrash.
>>
>
> Thanks Matt for the quick review. I will get the comments addressed and
> final patches uploaded quickly.
>

We have the updated patches ready. Just completing some testing. Should be
posting sometime this week.

Regards
Shobhit


>
> Regards
> Shobhit
>
>
>> Thanks.
>>
>>
>> Matt
>>
>>
>>> Especially "drm/i915/skl+: Use fb size for relative data rate
>>> calculation"
>>> this already addresses some of Ville's comment on similar patch from
>>> Matt.
>>>
>>> Regards
>>> Shobhit
>>>
>>> Kumar, Mahesh (6):
>>>drm/i915/skl+: Use proper bytes_per_pixel during WM calculation
>>>drm/i915/skl+: Use fb size for relative data rate calculation
>>>drm/i915/skl+: calculate ddb minimum allocation
>>>drm/i915/skl+: calculate plane pixel rate.
>>>drm/i915/skl+: Use scaling amount for plane data rate calculation
>>>drm/i915/skl: WA for watermark calculation based on Arbitrated Display
>>>  BW
>>>
>>> Shobhit Kumar (1):
>>>drm/i915: Add support to parse DMI table and get platform memory info
>>>
>>>   drivers/gpu/drm/i915/i915_dma.c  |  19 +++
>>>   drivers/gpu/drm/i915/i915_drv.h  |  15 ++
>>>   drivers/gpu/drm/i915/intel_drv.h |   2 +
>>>   drivers/gpu/drm/i915/intel_pm.c  | 294
>>> +--
>>>   4 files changed, 316 insertions(+), 14 deletions(-)
>>>
>>> --
>>> 2.4.3
>>>
>>>
>> ___
> Intel-gfx mailing list
> Intel-gfx@lists.freedesktop.org
> http://lists.freedesktop.org/mailman/listinfo/intel-gfx
>
___
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/intel-gfx


[Intel-gfx] [v2 6/6] drm/i915/skl: WA for watermark calculation based on Arbitrated Display BW

2016-01-27 Thread Shobhit Kumar
From: "Kumar, Mahesh" 

 If the arbitary display bandwidth is > 60% of memory bandwith, for
 x-tile we should increase latency at all levels by 15us.

 If the arbitary dsplay bandwidth is greater than 20% of memory bandwith
 in case of y-tile  being enabled, double the scan lines

v2: Update the commit message to explain the WA (shobhit)

v3: - Address Damien's comment, use DIV_ROUND_UP_ULL macro
- Check both mem_speed and mem_channel to be valid before applying
  WA(shobhit)

Signed-off-by: Shobhit Kumar 
Signed-off-by: Kumar, Mahesh 
Signed-off-by: Shobhit Kumar 
---
 drivers/gpu/drm/i915/i915_drv.h |  9 
 drivers/gpu/drm/i915/intel_pm.c | 92 +
 2 files changed, 101 insertions(+)

diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h
index b040e7a..450e6d3 100644
--- a/drivers/gpu/drm/i915/i915_drv.h
+++ b/drivers/gpu/drm/i915/i915_drv.h
@@ -1624,6 +1624,12 @@ enum intel_pipe_crc_source {
INTEL_PIPE_CRC_SOURCE_MAX,
 };
 
+enum watermark_memory_wa {
+   WATERMARK_WA_NONE,
+   WATERMARK_WA_X_TILED,
+   WATERMARK_WA_Y_TILED,
+};
+
 struct intel_pipe_crc_entry {
uint32_t frame;
uint32_t crc[5];
@@ -1926,6 +1932,9 @@ struct drm_i915_private {
/* Committed wm config */
struct intel_wm_config config;
 
+   /* This stores if WaterMark memory workaround is needed */
+   enum watermark_memory_wa mem_wa;
+
/*
 * The skl_wm_values structure is a bit too big for stack
 * allocation, so we keep the staging struct where we store
diff --git a/drivers/gpu/drm/i915/intel_pm.c b/drivers/gpu/drm/i915/intel_pm.c
index a9f9396..da5ff34 100644
--- a/drivers/gpu/drm/i915/intel_pm.c
+++ b/drivers/gpu/drm/i915/intel_pm.c
@@ -3225,6 +3225,11 @@ static bool skl_compute_plane_wm(const struct 
drm_i915_private *dev_priv,
if (latency == 0 || !cstate->base.active || !intel_pstate->visible)
return false;
 
+   if (dev_priv->wm.mem_wa != WATERMARK_WA_NONE) {
+   if (fb->modifier[0] == I915_FORMAT_MOD_X_TILED)
+   latency += 15;
+   }
+
width = drm_rect_width(&intel_pstate->src) >> 16;
height = drm_rect_height(&intel_pstate->src) >> 16;
 
@@ -3265,6 +3270,9 @@ static bool skl_compute_plane_wm(const struct 
drm_i915_private *dev_priv,
WARN(1, "Unsupported pixel depth for rotation");
}
}
+   if (dev_priv->wm.mem_wa == WATERMARK_WA_Y_TILED)
+   min_scanlines *= 2;
+
y_tile_minimum = plane_blocks_per_line * min_scanlines;
selected_result = max(method2, y_tile_minimum);
} else {
@@ -3715,6 +3723,89 @@ static void skl_set_plane_pixel_rate(struct drm_crtc 
*crtc)
 
 }
 
+static void
+skl_set_display_memory_wa(struct drm_device *dev)
+{
+   struct drm_i915_private *dev_priv = dev->dev_private;
+   struct intel_crtc *intel_crtc = NULL;
+   struct intel_plane *intel_plane = NULL;
+   uint32_t num_active_crtc = 0;
+   uint64_t max_pixel_rate_pipe = 0;
+   uint64_t display_bw = 0, available_bw = 0;
+   bool y_tile_enabled = false;
+   int memory_portion = 0;
+
+   /* Verify that we got proper memory information */
+   if (dev_priv->dmi.mem_channel == 0 || dev_priv->dmi.mem_speed == -1) {
+   dev_priv->wm.mem_wa = WATERMARK_WA_NONE;
+   return;
+   }
+
+   for_each_intel_crtc(dev, intel_crtc) {
+   uint64_t max_pixel_rate_plane = 0;
+   uint64_t pipe_bw;
+   uint32_t num_active_plane = 0;
+   const struct intel_crtc_state *cstate = NULL;
+
+   if (!intel_crtc->active)
+   continue;
+   cstate = to_intel_crtc_state(intel_crtc->base.state);
+   num_active_crtc++;
+
+   for_each_intel_plane_on_crtc(dev, intel_crtc, intel_plane) {
+   struct drm_plane *plane = &intel_plane->base;
+   struct drm_framebuffer *fb = plane->state->fb;
+   uint64_t plane_bw, interm_bw = 1000;
+
+   if (fb == NULL)
+   continue;
+   if (plane->type == DRM_PLANE_TYPE_CURSOR)
+   continue;
+   num_active_plane++;
+
+   if (fb->modifier[0] == I915_FORMAT_MOD_Y_TILED)
+   y_tile_enabled = true;
+
+   /*
+* planeBW = pixel_rate(MHz) * BPP * plane downscale
+*  amount * pipe downscale amount;
+*
+ 

[Intel-gfx] [v2 3/6] drm/i915/skl+: calculate plane pixel rate

2016-01-27 Thread Shobhit Kumar
From: "Kumar, Mahesh" 

Don't use pipe pixel rate for plane pixel rate. Calculate plane pixel according
to formula

adjusted plane_pixel_rate = adjusted pipe_pixel_rate * downscale ammount

downscale amount = max[1, src_h/dst_h] * max[1, src_w/dst_w]
if 90/270 rotation use rotated width & height

v2: use intel_plane_state->visible instead of (fb == NULL) as per Matt's
comment.

Cc: matthew.d.ro...@intel.com
Signed-off-by: Kumar, Mahesh 
---
 drivers/gpu/drm/i915/intel_drv.h |  2 +
 drivers/gpu/drm/i915/intel_pm.c  | 88 +++-
 2 files changed, 88 insertions(+), 2 deletions(-)

diff --git a/drivers/gpu/drm/i915/intel_drv.h b/drivers/gpu/drm/i915/intel_drv.h
index bc97012..bb2b1c7 100644
--- a/drivers/gpu/drm/i915/intel_drv.h
+++ b/drivers/gpu/drm/i915/intel_drv.h
@@ -638,6 +638,8 @@ struct intel_plane_wm_parameters {
u64 tiling;
unsigned int rotation;
uint16_t fifo_size;
+   /* Stores the adjusted plane pixel rate for WM calculation for SKL+ */
+   uint32_t plane_pixel_rate;
 };
 
 struct intel_plane {
diff --git a/drivers/gpu/drm/i915/intel_pm.c b/drivers/gpu/drm/i915/intel_pm.c
index 708f329..40fff09 100644
--- a/drivers/gpu/drm/i915/intel_pm.c
+++ b/drivers/gpu/drm/i915/intel_pm.c
@@ -2782,6 +2782,48 @@ skl_wm_plane_id(const struct intel_plane *plane)
}
 }
 
+/*
+ * This function takes drm_plane_state as input
+ * and decides the downscale amount according to the formula
+ *
+ * downscale amount = Max[1, Horizontal source size / Horizontal dest size]
+ *
+ * Return value is multiplied by 1000 to retain fractional part
+ * Caller should take care of dividing & Rounding off the value
+ */
+static uint32_t
+skl_plane_downscale_amount(const struct intel_plane *intel_plane)
+{
+   struct drm_plane_state *pstate = intel_plane->base.state;
+   struct intel_plane_state *intel_pstate = to_intel_plane_state(pstate);
+   uint32_t downscale_h, downscale_w;
+   uint32_t src_w, src_h, dst_w, dst_h, tmp;
+
+   /* If plane not visible return amount as unity */
+   if (!intel_pstate->visible)
+   return 1000;
+
+   src_w = drm_rect_width(&intel_pstate->src) >> 16;
+   src_h = drm_rect_height(&intel_pstate->src) >> 16;
+
+   dst_w = drm_rect_width(&intel_pstate->dst);
+   dst_h = drm_rect_height(&intel_pstate->dst);
+
+   if (intel_rotation_90_or_270(pstate->rotation))
+   swap(dst_w, dst_h);
+
+   /* Multiply by 1000 for precision */
+   tmp = (1000 * src_h) / dst_h;
+   downscale_h = max_t(uint32_t, 1000, tmp);
+
+   tmp = (1000 * src_w) / dst_w;
+   downscale_w = max_t(uint32_t, 1000, tmp);
+
+   /* Reducing precision to 3 decimal places */
+   return DIV_ROUND_UP(downscale_h * downscale_w, 1000);
+}
+
+
 static void
 skl_ddb_get_pipe_allocation_limits(struct drm_device *dev,
   const struct intel_crtc_state *cstate,
@@ -3183,10 +3225,10 @@ static bool skl_compute_plane_wm(const struct 
drm_i915_private *dev_priv,
swap(width, height);
 
bytes_per_pixel = drm_format_plane_cpp(fb->pixel_format, 0);
-   method1 = skl_wm_method1(skl_pipe_pixel_rate(cstate),
+   method1 = skl_wm_method1(intel_plane->wm.plane_pixel_rate,
 bytes_per_pixel,
 latency);
-   method2 = skl_wm_method2(skl_pipe_pixel_rate(cstate),
+   method2 = skl_wm_method2(intel_plane->wm.plane_pixel_rate,
 cstate->base.adjusted_mode.crtc_htotal,
 width,
 bytes_per_pixel,
@@ -3627,6 +3669,45 @@ static void skl_update_other_pipe_wm(struct drm_device 
*dev,
}
 }
 
+static uint32_t
+skl_plane_pixel_rate(struct intel_crtc_state *cstate, struct intel_plane 
*plane)
+{
+   uint32_t adjusted_pixel_rate;
+   uint32_t downscale_amount;
+
+   /*
+* adjusted plane pixel rate = adjusted pipe pixel rate
+* Plane pixel rate = adjusted plane pixel rate * plane down scale
+* amount
+*/
+   adjusted_pixel_rate = skl_pipe_pixel_rate(cstate);
+   downscale_amount = skl_plane_downscale_amount(plane);
+
+   return DIV_ROUND_UP(adjusted_pixel_rate * downscale_amount,
+   1000);
+}
+
+static void skl_set_plane_pixel_rate(struct drm_crtc *crtc)
+{
+   struct intel_crtc *intel_crtc = to_intel_crtc(crtc);
+   struct intel_crtc_state *cstate = to_intel_crtc_state(crtc->state);
+   struct intel_plane *intel_plane = NULL;
+   struct drm_device *dev = crtc->dev;
+
+   if (!intel_crtc->active)
+   return;
+   for_each_intel_plane_on_crtc(dev, intel_crtc, intel_plane) {
+   struct drm_plane *plane = &intel_plane->base;
+
+   if (!to_intel_plane_state(plane->state)->visible)
+   continue;
+
+   intel_plane->wm.plane_pixel_ra

[Intel-gfx] [v2 2/6] drm/i915/skl+: calculate ddb minimum allocation

2016-01-27 Thread Shobhit Kumar
From: "Kumar, Mahesh" 

don't always use 8 ddb as minimum, instead calculate using proper
algorithm.

v2: optimizations as per Matt's comments.

Cc: matthew.d.ro...@intel.com
Signed-off-by: Kumar, Mahesh 
---
 drivers/gpu/drm/i915/intel_pm.c | 50 ++---
 1 file changed, 47 insertions(+), 3 deletions(-)

diff --git a/drivers/gpu/drm/i915/intel_pm.c b/drivers/gpu/drm/i915/intel_pm.c
index d55e5d0..708f329 100644
--- a/drivers/gpu/drm/i915/intel_pm.c
+++ b/drivers/gpu/drm/i915/intel_pm.c
@@ -2928,6 +2928,51 @@ skl_get_total_relative_data_rate(const struct 
intel_crtc_state *cstate)
return total_data_rate;
 }
 
+static uint16_t
+skl_ddb_min_alloc(const struct intel_crtc *crtc,
+   const struct drm_plane *plane, int y)
+{
+   struct drm_framebuffer *fb = plane->state->fb;
+   struct intel_plane_state *pstate = to_intel_plane_state(plane->state);
+   uint32_t src_w, src_h;
+   uint32_t min_scanlines = 8;
+   uint8_t bytes_per_pixel;
+
+   /* For packed formats, no y-plane, return 0 */
+   if (y && !fb && !(fb->pixel_format == DRM_FORMAT_NV12))
+   return 0;
+
+   /* For Non Y-tile return 8-blocks */
+   if (!(fb->modifier[0] == I915_FORMAT_MOD_Y_TILED) &&
+   !(fb->modifier[0] == I915_FORMAT_MOD_Yf_TILED))
+   return 8;
+
+   src_w = drm_rect_width(&pstate->src) >> 16;
+   src_h = drm_rect_height(&pstate->src) >> 16;
+
+   if (intel_rotation_90_or_270(plane->state->rotation))
+   swap(src_w, src_h);
+
+   bytes_per_pixel = y ? drm_format_plane_cpp(fb->pixel_format, 0) :
+   drm_format_plane_cpp(fb->pixel_format, 1);
+
+   if (intel_rotation_90_or_270(plane->state->rotation)) {
+   switch (bytes_per_pixel) {
+   case 1:
+   min_scanlines = 32;
+   break;
+   case 2:
+   min_scanlines = 16;
+   break;
+   case 8:
+   WARN(1, "Unsupported pixel depth for rotation");
+   }
+   }
+
+   return DIV_ROUND_UP((4 * src_w / (y ? 1 : 2) * bytes_per_pixel), 512) *
+   min_scanlines/4 + 3;
+}
+
 static void
 skl_allocate_pipe_ddb(struct intel_crtc_state *cstate,
  struct skl_ddb_allocation *ddb /* out */)
@@ -2964,7 +3009,6 @@ skl_allocate_pipe_ddb(struct intel_crtc_state *cstate,
/* 1. Allocate the mininum required blocks for each active plane */
for_each_intel_plane_on_crtc(dev, intel_crtc, intel_plane) {
struct drm_plane *plane = &intel_plane->base;
-   struct drm_framebuffer *fb = plane->state->fb;
int id = skl_wm_plane_id(intel_plane);
 
if (!to_intel_plane_state(plane->state)->visible)
@@ -2973,9 +3017,9 @@ skl_allocate_pipe_ddb(struct intel_crtc_state *cstate,
if (plane->type == DRM_PLANE_TYPE_CURSOR)
continue;
 
-   minimum[id] = 8;
+   minimum[id] = skl_ddb_min_alloc(intel_crtc, plane, 0);
alloc_size -= minimum[id];
-   y_minimum[id] = (fb->pixel_format == DRM_FORMAT_NV12) ? 8 : 0;
+   y_minimum[id] = skl_ddb_min_alloc(intel_crtc, plane, 1);
alloc_size -= y_minimum[id];
}
 
-- 
2.5.0

___
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/intel-gfx


[Intel-gfx] [v2 4/6] drm/i915/skl+: Use scaling amount for plane data rate calculation

2016-01-27 Thread Shobhit Kumar
From: "Kumar, Mahesh" 

if downscaling is enabled plane data rate increases according to scaling
amount. take scaling amount under consideration while calculating plane
data rate

v2: Address Matt's comments, where data rate was overridden because of
missing else.

Cc: matthew.d.ro...@intel.com
Signed-off-by: Kumar, Mahesh 
---
 drivers/gpu/drm/i915/intel_pm.c | 17 -
 1 file changed, 12 insertions(+), 5 deletions(-)

diff --git a/drivers/gpu/drm/i915/intel_pm.c b/drivers/gpu/drm/i915/intel_pm.c
index 40fff09..a9f9396 100644
--- a/drivers/gpu/drm/i915/intel_pm.c
+++ b/drivers/gpu/drm/i915/intel_pm.c
@@ -2912,6 +2912,8 @@ skl_plane_relative_data_rate(const struct 
intel_crtc_state *cstate,
 {
struct intel_plane_state *intel_pstate = to_intel_plane_state(pstate);
struct drm_framebuffer *fb = pstate->fb;
+   struct intel_plane *intel_plane = to_intel_plane(pstate->plane);
+   uint32_t down_scale_amount, data_rate;
uint32_t width = 0, height = 0;
 
width = drm_rect_width(&intel_pstate->src) >> 16;
@@ -2923,15 +2925,20 @@ skl_plane_relative_data_rate(const struct 
intel_crtc_state *cstate,
/* for planar format */
if (fb->pixel_format == DRM_FORMAT_NV12) {
if (y)  /* y-plane data rate */
-   return width * height *
+   data_rate = width * height *
drm_format_plane_cpp(fb->pixel_format, 0);
else/* uv-plane data rate */
-   return (width / 2) * (height / 2) *
+   data_rate = (width / 2) * (height / 2) *
drm_format_plane_cpp(fb->pixel_format, 1);
-   }
+   } else
+   /* for packed formats */
+   data_rate = width * height *
+   drm_format_plane_cpp(fb->pixel_format, 0);
+
+   down_scale_amount = skl_plane_downscale_amount(intel_plane);
+
+   return DIV_ROUND_UP((data_rate * down_scale_amount), 1000);
 
-   /* for packed formats */
-   return width * height * drm_format_plane_cpp(fb->pixel_format, 0);
 }
 
 /*
-- 
2.5.0

___
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/intel-gfx


[Intel-gfx] [v2 1/6] drm/i915/skl+: Use plane size for relative data rate calculation

2016-01-27 Thread Shobhit Kumar
From: "Kumar, Mahesh" 

Use plane size for relative data rate calculation. don't always use
pipe source width & height.
adjust height & width according to rotation.
use plane size for watermark calculations also.

v2: Address Matt's comments.
Use intel_plane_state->visible to avoid divide-by-zero error.
Where FB was present but not visible so causing total data rate to
be zero, hence divide-by-zero.

Cc: matthew.d.ro...@intel.com
Signed-off-by: Kumar, Mahesh 
---
 drivers/gpu/drm/i915/intel_pm.c | 42 ++---
 1 file changed, 27 insertions(+), 15 deletions(-)

diff --git a/drivers/gpu/drm/i915/intel_pm.c b/drivers/gpu/drm/i915/intel_pm.c
index 20bf854..d55e5d0 100644
--- a/drivers/gpu/drm/i915/intel_pm.c
+++ b/drivers/gpu/drm/i915/intel_pm.c
@@ -2868,25 +2868,28 @@ skl_plane_relative_data_rate(const struct 
intel_crtc_state *cstate,
 const struct drm_plane_state *pstate,
 int y)
 {
-   struct intel_crtc *intel_crtc = to_intel_crtc(cstate->base.crtc);
+   struct intel_plane_state *intel_pstate = to_intel_plane_state(pstate);
struct drm_framebuffer *fb = pstate->fb;
+   uint32_t width = 0, height = 0;
+
+   width = drm_rect_width(&intel_pstate->src) >> 16;
+   height = drm_rect_height(&intel_pstate->src) >> 16;
+
+   if (intel_rotation_90_or_270(pstate->rotation))
+   swap(width, height);
 
/* for planar format */
if (fb->pixel_format == DRM_FORMAT_NV12) {
if (y)  /* y-plane data rate */
-   return intel_crtc->config->pipe_src_w *
-   intel_crtc->config->pipe_src_h *
+   return width * height *
drm_format_plane_cpp(fb->pixel_format, 0);
else/* uv-plane data rate */
-   return (intel_crtc->config->pipe_src_w/2) *
-   (intel_crtc->config->pipe_src_h/2) *
+   return (width / 2) * (height / 2) *
drm_format_plane_cpp(fb->pixel_format, 1);
}
 
/* for packed formats */
-   return intel_crtc->config->pipe_src_w *
-   intel_crtc->config->pipe_src_h *
-   drm_format_plane_cpp(fb->pixel_format, 0);
+   return width * height * drm_format_plane_cpp(fb->pixel_format, 0);
 }
 
 /*
@@ -2905,9 +2908,8 @@ skl_get_total_relative_data_rate(const struct 
intel_crtc_state *cstate)
for_each_intel_plane_on_crtc(dev, intel_crtc, intel_plane) {
const struct drm_plane_state *pstate = intel_plane->base.state;
 
-   if (pstate->fb == NULL)
+   if (!to_intel_plane_state(pstate)->visible)
continue;
-
if (intel_plane->base.type == DRM_PLANE_TYPE_CURSOR)
continue;
 
@@ -2965,8 +2967,9 @@ skl_allocate_pipe_ddb(struct intel_crtc_state *cstate,
struct drm_framebuffer *fb = plane->state->fb;
int id = skl_wm_plane_id(intel_plane);
 
-   if (fb == NULL)
+   if (!to_intel_plane_state(plane->state)->visible)
continue;
+
if (plane->type == DRM_PLANE_TYPE_CURSOR)
continue;
 
@@ -2992,7 +2995,7 @@ skl_allocate_pipe_ddb(struct intel_crtc_state *cstate,
uint16_t plane_blocks, y_plane_blocks = 0;
int id = skl_wm_plane_id(intel_plane);
 
-   if (pstate->fb == NULL)
+   if (!to_intel_plane_state(pstate)->visible)
continue;
if (plane->type == DRM_PLANE_TYPE_CURSOR)
continue;
@@ -3116,28 +3119,37 @@ static bool skl_compute_plane_wm(const struct 
drm_i915_private *dev_priv,
 {
struct drm_plane *plane = &intel_plane->base;
struct drm_framebuffer *fb = plane->state->fb;
+   struct intel_plane_state *intel_pstate =
+   to_intel_plane_state(plane->state);
uint32_t latency = dev_priv->wm.skl_latency[level];
uint32_t method1, method2;
uint32_t plane_bytes_per_line, plane_blocks_per_line;
uint32_t res_blocks, res_lines;
uint32_t selected_result;
uint8_t bytes_per_pixel;
+   uint32_t width = 0, height = 0;
 
-   if (latency == 0 || !cstate->base.active || !fb)
+   if (latency == 0 || !cstate->base.active || !intel_pstate->visible)
return false;
 
+   width = drm_rect_width(&intel_pstate->src) >> 16;
+   height = drm_rect_height(&intel_pstate->src) >> 16;
+
+   if (intel_rotation_90_or_270(plane->state->rotation))
+   swap(width, height);
+
bytes_per_pixel = drm_format_plane_cpp(fb->pixel_format, 0);
method1 = skl_wm_method1(skl_pipe_pixel_rate(cstate),
 bytes_per_pixel,
   

[Intel-gfx] [v2 5/6] drm/i915: Add support to parse DMI table and get platform memory info

2016-01-27 Thread Shobhit Kumar
This is needed for WM computation workaround for arbitrated display
bandwidth.

v2: Address Matt's review comments
- Be more paranoid while dmi decoding
- Also add support for decoding speed from configured memory speed
  if availble in DMI memory entry

Cc: matthew.d.ro...@intel.com
Signed-off-by: Shobhit Kumar 
---
 drivers/gpu/drm/i915/i915_dma.c | 47 +
 drivers/gpu/drm/i915/i915_drv.h |  6 ++
 2 files changed, 53 insertions(+)

diff --git a/drivers/gpu/drm/i915/i915_dma.c b/drivers/gpu/drm/i915/i915_dma.c
index d70d96f..320143b 100644
--- a/drivers/gpu/drm/i915/i915_dma.c
+++ b/drivers/gpu/drm/i915/i915_dma.c
@@ -49,6 +49,7 @@
 #include 
 #include 
 #include 
+#include 
 
 
 static int i915_getparam(struct drm_device *dev, void *data,
@@ -855,6 +856,49 @@ static void intel_init_dpio(struct drm_i915_private 
*dev_priv)
}
 }
 
+static void dmi_decode_memory_info(const struct dmi_header *hdr, void *priv)
+{
+   struct drm_i915_private *dev_priv = (struct drm_i915_private *) priv;
+   const u8 *data = (const u8 *) hdr;
+   uint16_t size, mem_speed;
+
+#define DMI_CONF_MEM_SPEED_OFFSET  0x20
+#define DMI_MEM_SPEED_OFFSET   0x15
+#define DMI_MEM_SIZE_OFFSET0x0C
+
+   if (hdr->type == DMI_ENTRY_MEM_DEVICE) {
+   /* Found a memory channel ? */
+   size = (uint16_t) (*((uint16_t *)(data + DMI_MEM_SIZE_OFFSET)));
+   if (size == 0)
+   return;
+
+   dev_priv->dmi.mem_channel++;
+
+   /* Get the speed */
+   if (hdr->length > DMI_CONF_MEM_SPEED_OFFSET)
+   mem_speed =
+   (uint16_t) (*((uint16_t *)(data + 
DMI_CONF_MEM_SPEED_OFFSET)));
+   else if (hdr->length > DMI_MEM_SPEED_OFFSET)
+   mem_speed =
+   (uint16_t) (*((uint16_t *)(data + 
DMI_MEM_SPEED_OFFSET)));
+   else
+   mem_speed = -1;
+
+   /*
+* Check all channels have same speed
+* else mark speed as invalid
+*/
+   if (dev_priv->dmi.mem_speed == 0) {
+   if (mem_speed > 0)
+   dev_priv->dmi.mem_speed = mem_speed;
+   else
+   dev_priv->dmi.mem_speed = -1;
+   } else if (dev_priv->dmi.mem_speed > 0 &&
+   dev_priv->dmi.mem_speed != mem_speed)
+   dev_priv->dmi.mem_speed = -1;
+   }
+}
+
 /**
  * i915_driver_load - setup chip and create an initial config
  * @dev: DRM device
@@ -882,6 +926,9 @@ int i915_driver_load(struct drm_device *dev, unsigned long 
flags)
dev->dev_private = dev_priv;
dev_priv->dev = dev;
 
+   /* walk the dmi device table for getting platform memory information */
+   dmi_walk(dmi_decode_memory_info, (void *) dev_priv);
+
/* Setup the write-once "constant" device info */
device_info = (struct intel_device_info *)&dev_priv->info;
memcpy(device_info, info, sizeof(dev_priv->info));
diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h
index 211af53..b040e7a 100644
--- a/drivers/gpu/drm/i915/i915_drv.h
+++ b/drivers/gpu/drm/i915/i915_drv.h
@@ -1968,6 +1968,12 @@ struct drm_i915_private {
 * NOTE: This is the dri1/ums dungeon, don't add stuff here. Your patch
 * will be rejected. Instead look for a better place.
 */
+
+   /* DMI data for memory bandwidth calculation */
+   struct {
+   uint16_t mem_channel;
+   int16_t mem_speed;
+   } dmi;
 };
 
 static inline struct drm_i915_private *to_i915(const struct drm_device *dev)
-- 
2.5.0

___
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/intel-gfx


[Intel-gfx] [PATCH 1/3] drm/i915: Encapsulate the pwm_device in a pwm_info structure

2017-05-31 Thread Shobhit Kumar
pwm_info helps in encapsulating the PWM period_ns values and will form
basis of adding new pwm devices which can then be genrically used by
initializing proper pwm_info structure in the backlight setup call.

v2: Rebase on latest code. Add BZ details

Bugzilla: https://bugs.freedesktop.org/show_bug.cgi?id=96571
Bugzilla: https://bugs.freedesktop.org/show_bug.cgi?id=90075
Cc: cbroo...@gmail.com
Cc: jani.nik...@linux.intel.com
Tested-by: Lluís Batlle i Rossell 
Signed-off-by: Shobhit Kumar 
---
 drivers/gpu/drm/i915/intel_drv.h   |  8 ++-
 drivers/gpu/drm/i915/intel_panel.c | 47 +++---
 2 files changed, 36 insertions(+), 19 deletions(-)

diff --git a/drivers/gpu/drm/i915/intel_drv.h b/drivers/gpu/drm/i915/intel_drv.h
index cc13706..17af59c 100644
--- a/drivers/gpu/drm/i915/intel_drv.h
+++ b/drivers/gpu/drm/i915/intel_drv.h
@@ -263,6 +263,12 @@ struct intel_encoder {
const struct drm_connector *audio_connector;
 };
 
+struct intel_pwm_info {
+   struct pwm_device *dev;
+   unsigned int period_ns;
+   char *name;
+};
+
 struct intel_panel {
struct drm_display_mode *fixed_mode;
struct drm_display_mode *downclock_mode;
@@ -282,7 +288,7 @@ struct intel_panel {
/* PWM chip */
bool util_pin_active_low;   /* bxt+ */
u8 controller;  /* bxt+ only */
-   struct pwm_device *pwm;
+   struct intel_pwm_info *pwm;
 
struct backlight_device *device;
 
diff --git a/drivers/gpu/drm/i915/intel_panel.c 
b/drivers/gpu/drm/i915/intel_panel.c
index c8103f8..d56d1c2 100644
--- a/drivers/gpu/drm/i915/intel_panel.c
+++ b/drivers/gpu/drm/i915/intel_panel.c
@@ -37,6 +37,13 @@
 
 #define CRC_PMIC_PWM_PERIOD_NS 21333
 
+/* CRC PMIC based PWM Information */
+struct intel_pwm_info crc_pwm_info = {
+   .period_ns = CRC_PMIC_PWM_PERIOD_NS,
+   .name = "pwm_backlight",
+   .dev = NULL,
+};
+
 void
 intel_fixed_panel_mode(const struct drm_display_mode *fixed_mode,
   struct drm_display_mode *adjusted_mode)
@@ -536,10 +543,11 @@ static u32 bxt_get_backlight(struct intel_connector 
*connector)
 static u32 pwm_get_backlight(struct intel_connector *connector)
 {
struct intel_panel *panel = &connector->panel;
+   struct intel_pwm_info *pwm = panel->backlight.pwm;
int duty_ns;
 
-   duty_ns = pwm_get_duty_cycle(panel->backlight.pwm);
-   return DIV_ROUND_UP(duty_ns * 100, CRC_PMIC_PWM_PERIOD_NS);
+   duty_ns = pwm_get_duty_cycle(pwm->dev);
+   return DIV_ROUND_UP(duty_ns * 100, pwm->period_ns);
 }
 
 static u32 intel_panel_get_backlight(struct intel_connector *connector)
@@ -628,9 +636,10 @@ static void bxt_set_backlight(struct intel_connector 
*connector, u32 level)
 static void pwm_set_backlight(struct intel_connector *connector, u32 level)
 {
struct intel_panel *panel = &connector->panel;
-   int duty_ns = DIV_ROUND_UP(level * CRC_PMIC_PWM_PERIOD_NS, 100);
+   struct intel_pwm_info *pwm = panel->backlight.pwm;
+   int duty_ns = DIV_ROUND_UP(level * pwm->period_ns, 100);
 
-   pwm_config(panel->backlight.pwm, duty_ns, CRC_PMIC_PWM_PERIOD_NS);
+   pwm_config(pwm->dev, duty_ns, pwm->period_ns);
 }
 
 static void
@@ -799,11 +808,12 @@ static void bxt_disable_backlight(struct intel_connector 
*connector)
 static void pwm_disable_backlight(struct intel_connector *connector)
 {
struct intel_panel *panel = &connector->panel;
+   struct intel_pwm_info *pwm = panel->backlight.pwm;
 
/* Disable the backlight */
-   pwm_config(panel->backlight.pwm, 0, CRC_PMIC_PWM_PERIOD_NS);
+   pwm_config(pwm->dev, 0, pwm->period_ns);
usleep_range(2000, 3000);
-   pwm_disable(panel->backlight.pwm);
+   pwm_disable(pwm->dev);
 }
 
 void intel_panel_disable_backlight(struct intel_connector *connector)
@@ -1090,7 +1100,7 @@ static void pwm_enable_backlight(struct intel_connector 
*connector)
 {
struct intel_panel *panel = &connector->panel;
 
-   pwm_enable(panel->backlight.pwm);
+   pwm_enable(panel->backlight.pwm->dev);
intel_panel_actually_set_backlight(connector, panel->backlight.level);
 }
 
@@ -1649,12 +1659,13 @@ static int pwm_setup_backlight(struct intel_connector 
*connector,
 {
struct drm_device *dev = connector->base.dev;
struct intel_panel *panel = &connector->panel;
+   struct intel_pwm_info *pwm = &crc_pwm_info;
int retval;
 
/* Get the PWM chip for backlight control */
-   panel->backlight.pwm = pwm_get(dev->dev, "pwm_backlight");
-   if (IS_ERR(panel->backlight.pwm)) {
-   DRM_ERROR("Failed to own the pwm chip\n");
+   pwm->dev = pwm_get(dev->dev, pwm->name);
+   if (IS_ERR(pwm->dev)) {
+   DRM_ERROR("

[Intel-gfx] [PATCH 0/3] Reviving the PWM_LPSS patches yet again

2017-05-31 Thread Shobhit Kumar
Hi All,
Its been long since I have been sitting on these after I had received Tested-by
for the same by Lluís for atleast the backlight working fine. The related bugs 
are - 

https://bugs.freedesktop.org/show_bug.cgi?id=96571
https://bugs.freedesktop.org/show_bug.cgi?id=90075

Rebased the code on latest code and sending again. Still display was not working
on devices referenced in these bugs but backlight control was tested to be 
working
at that time. DSI issues of panel display not comming up is tracked separately 
at -
https://bugs.freedesktop.org/show_bug.cgi?id=96923 and should be again tested 
with 
latest drm-tip.

Module ordering problem remains still and for testing we should for now enable
LPSS_PWM as in built with i915 as module.

Regards
Shobhit

Shobhit Kumar (3):
  drm/i915: Encapsulate the pwm_device in a pwm_info structure
  pwm: lpss: Add intel-gfx as consumer device in lookup table
  drm/i915: Add support for LPSS PWM on devices that support it

 drivers/gpu/drm/i915/intel_drv.h   |  8 -
 drivers/gpu/drm/i915/intel_panel.c | 61 +++---
 drivers/pwm/pwm-lpss-platform.c| 12 
 3 files changed, 62 insertions(+), 19 deletions(-)

-- 
2.7.4

___
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/intel-gfx


[Intel-gfx] [PATCH 3/3] drm/i915: Add support for LPSS PWM on devices that support it

2017-05-31 Thread Shobhit Kumar
v2: Add bugzilla links

Bugzilla: https://bugs.freedesktop.org/show_bug.cgi?id=96571
Bugzilla: https://bugs.freedesktop.org/show_bug.cgi?id=90075
Cc: cbroo...@gmail.com
Cc: jani.nik...@linux.intel.com
Tested-by: Lluís Batlle i Rossell 
Signed-off-by: Shobhit Kumar 
---
 drivers/gpu/drm/i915/intel_panel.c | 16 +++-
 1 file changed, 15 insertions(+), 1 deletion(-)

diff --git a/drivers/gpu/drm/i915/intel_panel.c 
b/drivers/gpu/drm/i915/intel_panel.c
index d56d1c2..4d84c561 100644
--- a/drivers/gpu/drm/i915/intel_panel.c
+++ b/drivers/gpu/drm/i915/intel_panel.c
@@ -36,6 +36,7 @@
 #include "intel_drv.h"
 
 #define CRC_PMIC_PWM_PERIOD_NS 21333
+#define LPSS_PWM_PERIOD_NS 10240
 
 /* CRC PMIC based PWM Information */
 struct intel_pwm_info crc_pwm_info = {
@@ -44,6 +45,13 @@ struct intel_pwm_info crc_pwm_info = {
.dev = NULL,
 };
 
+/* LPSS based PWM Information */
+struct intel_pwm_info lpss_pwm_info = {
+   .period_ns = LPSS_PWM_PERIOD_NS,
+   .name = "pwm_lpss",
+   .dev = NULL,
+};
+
 void
 intel_fixed_panel_mode(const struct drm_display_mode *fixed_mode,
   struct drm_display_mode *adjusted_mode)
@@ -1658,10 +1666,16 @@ static int pwm_setup_backlight(struct intel_connector 
*connector,
   enum pipe pipe)
 {
struct drm_device *dev = connector->base.dev;
+   struct drm_i915_private *dev_priv = to_i915(connector->base.dev);
struct intel_panel *panel = &connector->panel;
-   struct intel_pwm_info *pwm = &crc_pwm_info;
+   struct intel_pwm_info *pwm;
int retval;
 
+   if (dev_priv->vbt.dsi.config->pwm_blc == PPS_BLC_PMIC)
+   pwm = &crc_pwm_info;
+   else /* PPS_BLC_SOC */
+   pwm = &lpss_pwm_info;
+
/* Get the PWM chip for backlight control */
pwm->dev = pwm_get(dev->dev, pwm->name);
if (IS_ERR(pwm->dev)) {
-- 
2.7.4

___
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/intel-gfx


[Intel-gfx] [PATCH 2/3] pwm: lpss: Add intel-gfx as consumer device in lookup table

2017-05-31 Thread Shobhit Kumar
v2: Rebase on latest code and correct the device name in
lookup table (viric)
Remove lookup table on driver remove

Bugzilla: https://bugs.freedesktop.org/show_bug.cgi?id=96571
Bugzilla: https://bugs.freedesktop.org/show_bug.cgi?id=90075
Cc: cbroo...@gmail.com
Cc: jani.nik...@linux.intel.com
Tested-by: Lluís Batlle i Rossell 
Signed-off-by: Shobhit Kumar 
---
 drivers/pwm/pwm-lpss-platform.c | 12 
 1 file changed, 12 insertions(+)

diff --git a/drivers/pwm/pwm-lpss-platform.c b/drivers/pwm/pwm-lpss-platform.c
index 5d6ed15..f157a6d 100644
--- a/drivers/pwm/pwm-lpss-platform.c
+++ b/drivers/pwm/pwm-lpss-platform.c
@@ -40,6 +40,11 @@ static const struct pwm_lpss_boardinfo pwm_lpss_bxt_info = {
.bypass = true,
 };
 
+/* PWM consumed by the Intel GFX */
+static struct pwm_lookup lpss_pwm_lookup[] = {
+   PWM_LOOKUP("80860F09:00", 0, ":00:02.0", "pwm_lpss", 0, 
PWM_POLARITY_NORMAL),
+};
+
 static int pwm_lpss_probe_platform(struct platform_device *pdev)
 {
const struct pwm_lpss_boardinfo *info;
@@ -60,6 +65,9 @@ static int pwm_lpss_probe_platform(struct platform_device 
*pdev)
 
platform_set_drvdata(pdev, lpwm);
 
+   /* Register intel-gfx device as allowed consumer */
+   pwm_add_table(lpss_pwm_lookup, ARRAY_SIZE(lpss_pwm_lookup));
+
pm_runtime_set_active(&pdev->dev);
pm_runtime_enable(&pdev->dev);
 
@@ -71,6 +79,10 @@ static int pwm_lpss_remove_platform(struct platform_device 
*pdev)
struct pwm_lpss_chip *lpwm = platform_get_drvdata(pdev);
 
pm_runtime_disable(&pdev->dev);
+
+   /* remove lookup table */
+   pwm_remove_table(lpss_pwm_lookup, ARRAY_SIZE(lpss_pwm_lookup));
+
return pwm_lpss_remove(lpwm);
 }
 
-- 
2.7.4

___
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/intel-gfx


Re: [Intel-gfx] [PATCH 00/11] Enable PSR on Haswell.

2013-07-15 Thread Shobhit Kumar

On Friday 12 July 2013 03:14 AM, Rodrigo Vivi wrote:

I'm resending full series again because after accepting most of suggestions
and rebasing again on drm-intel-nightly most of patches got some kind of
conflict so the full series is here again.

First 3 patches on this series are already reviewed and I'd be glad if they
were merged asap to avoid future conflicts. This patches at least allows
people to know if they have psr panel or not.

For the rest I accepted most of suggestions and explained on previous emails
the ones I didn't accepted and why. However even the ones I didn't accepted
I tested and verified that they caused some kind of issue.

This version is working very fine for a long time in my machine. I'd appreciate 
if you could merge everything since now psr is disabled by default by kernel 
flag. So I'm 100% sure that this series won't cause any kind of regression for 
any user.

I understand that it would be good to deliver psr enabled by default however 
I'm changing this default behaviour because I'm sure that PSR will cause 
regression without userspace (DDX) help when using kde and xdm.

Thanks in advance,
Rodrigo.

Rodrigo Vivi (9):
   drm/i915: split aux_clock_divider logic in a separated function for
 reuse.
   drm/i915: Enable/Disable PSR
   drm/i915: Added debugfs support for PSR Status
   drm/i915: Match all PSR mode entry conditions before enabling it.
   drm/i915: add update function to disable/enable-back PSR
   drm/intel: add enable_psr module option and disable psr by default
   drm/i915: Adding global I915_PARAM for PSR ENABLED.
   drm/i915: Add functions to force psr exit
   drm/i915: Hook PSR functionality

Shobhit Kumar (2):
   drm: Added SDP and VSC structures for handling PSR for eDP
   drm/i915: Read the EDP DPCD and PSR Capability

  drivers/gpu/drm/i915/i915_debugfs.c  | 128 
  drivers/gpu/drm/i915/i915_dma.c  |   3 +
  drivers/gpu/drm/i915/i915_drv.c  |   4 +
  drivers/gpu/drm/i915/i915_drv.h  |  15 ++
  drivers/gpu/drm/i915/i915_gem.c  |   2 +
  drivers/gpu/drm/i915/i915_reg.h  |  74 +++
  drivers/gpu/drm/i915/intel_ddi.c |   2 +
  drivers/gpu/drm/i915/intel_display.c |   1 +
  drivers/gpu/drm/i915/intel_dp.c  | 373 ---
  drivers/gpu/drm/i915/intel_drv.h |  10 +
  include/drm/drm_dp_helper.h  |  31 ++-
  include/uapi/drm/i915_drm.h  |   1 +
  12 files changed, 618 insertions(+), 26 deletions(-)



All looks good from code point of view. Not yet tested on a HSW system 
as I do not have one right now.


Reviewed-by: Shobhit Kumar 
___
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/intel-gfx


[Intel-gfx] [PATCH v3] drm/i915: Add parsing support for new MIPI blocks in VBT

2014-04-13 Thread Shobhit Kumar
The parser extracts the config block(#52) and sequence(#53) data
and store in private data structures.

v2: Address review comments by Jani
- adjust code for the structure changes for bdb_mipi_config
- add boundry and buffer overflow checks as suggested
- use kmemdup instead of kmalloc and memcpy

v3: More strict check while parsing VBT
- Ensure that at anytime we do not go beyond sequence block
  while parsing
- On unknown element fail the whole parsing

v4: Style changes and spell check mostly as suggested by Jani

Signed-off-by: Shobhit Kumar 
Reviewed-by: Jani Nikula 
---
 drivers/gpu/drm/i915/i915_drv.h   |   6 ++
 drivers/gpu/drm/i915/intel_bios.c | 204 +-
 drivers/gpu/drm/i915/intel_bios.h |  31 ++
 3 files changed, 236 insertions(+), 5 deletions(-)

diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h
index 85e362f..1b763aa 100644
--- a/drivers/gpu/drm/i915/i915_drv.h
+++ b/drivers/gpu/drm/i915/i915_drv.h
@@ -1170,6 +1170,12 @@ struct intel_vbt_data {
/* MIPI DSI */
struct {
u16 panel_id;
+   struct mipi_config *config;
+   struct mipi_pps_data *pps;
+   u8 seq_version;
+   u32 size;
+   u8 *data;
+   u8 *sequence[MIPI_SEQ_MAX];
} dsi;
 
int crt_ddc_pin;
diff --git a/drivers/gpu/drm/i915/intel_bios.c 
b/drivers/gpu/drm/i915/intel_bios.c
index 862ca04..917f5bb 100644
--- a/drivers/gpu/drm/i915/intel_bios.c
+++ b/drivers/gpu/drm/i915/intel_bios.c
@@ -636,19 +636,213 @@ parse_edp(struct drm_i915_private *dev_priv, struct 
bdb_header *bdb)
}
 }
 
+static u8 *goto_next_sequence(u8 *data, int *size)
+{
+   u16 len;
+   int tmp = *size;
+
+   if (--tmp < 0)
+   return NULL;
+
+   /* goto first element */
+   data++;
+   while (1) {
+   switch (*data) {
+   case MIPI_SEQ_ELEM_SEND_PKT:
+   /*
+* skip by this element payload size
+* skip elem id, command flag and data type
+*/
+   if ((tmp = tmp - 5) < 0)
+   return NULL;
+
+   data += 3;
+   len = *((u16 *)data);
+
+   if ((tmp = tmp - len) < 0)
+   return NULL;
+
+   /* skip by len */
+   data = data + 2 + len;
+   break;
+   case MIPI_SEQ_ELEM_DELAY:
+   /* skip by elem id, and delay is 4 bytes */
+   if ((tmp = tmp - 5) < 0)
+   return NULL;
+
+   data += 5;
+   break;
+   case MIPI_SEQ_ELEM_GPIO:
+   if ((tmp = tmp - 3) < 0)
+   return NULL;
+
+   data += 3;
+   break;
+   default:
+   DRM_ERROR("Unknown element\n");
+   return NULL;
+   }
+
+   /* end of sequence ? */
+   if (*data == 0)
+   break;
+   }
+
+   /* goto next sequence or end of block byte */
+   if (--tmp < 0)
+   return NULL;
+
+   data++;
+
+   /* update amount of data left for the sequence block to be parsed */
+   *size = tmp;
+   return data;
+}
+
 static void
 parse_mipi(struct drm_i915_private *dev_priv, struct bdb_header *bdb)
 {
-   struct bdb_mipi *mipi;
+   struct bdb_mipi_config *start;
+   struct bdb_mipi_sequence *sequence;
+   struct mipi_config *config;
+   struct mipi_pps_data *pps;
+   u8 *data, *seq_data;
+   int i, panel_id, seq_size;
+   u16 block_size;
+
+   /* Initialize this to undefined indicating no generic MIPI support */
+   dev_priv->vbt.dsi.panel_id = MIPI_DSI_UNDEFINED_PANEL_ID;
+
+   /* Block #40 is already parsed and panel_fixed_mode is
+* stored in dev_priv->lfp_lvds_vbt_mode
+* resuse this when needed
+*/
 
-   mipi = find_section(bdb, BDB_MIPI_CONFIG);
-   if (!mipi) {
-   DRM_DEBUG_KMS("No MIPI BDB found");
+   /* Parse #52 for panel index used from panel_type already
+* parsed
+*/
+   start = find_section(bdb, BDB_MIPI_CONFIG);
+   if (!start) {
+   DRM_DEBUG_KMS("No MIPI config BDB found");
return;
}
 
-   /* XXX: add more info */
+   DRM_DEBUG_DRIVER("Found MIPI Config block, panel index = %d\n",
+   panel_type);
+
+   /*
+* get hold of the correct configuration block and pps data as per
+* the panel_type as index
+*/
+ 

[Intel-gfx] [PATCH 0/4] Generic MIPI Panel driver

2014-04-13 Thread Shobhit Kumar
Hi,
This series enabled generic MIPI panel driver support, the ground for which
has been built up from the patches - 

http://lists.freedesktop.org/archives/intel-gfx/2014-February/040764.html
http://lists.freedesktop.org/archives/intel-gfx/2014-April/043646.html

With a version of these patches Asus T100A was found to be working by Arjan
who has a device. I do not have the device to test directly. Will be getting
one and verifying on that. But ideally should work. I have verified these 
patches 
on couple of internal panels.

Also some minor changes in intel_dsi.c to support the generic panel driver
are done.

Regards
Shobhit

Shobhit Kumar (4):
  drm/i915: Correct MIPI operation mode as per expected values from VBT
  drm/i915: MIPI init count programming as generic parameter
  drm/i915: MIPI PPS delays added
  drm/i915: Add support for Generic MIPI panel driver

 drivers/gpu/drm/i915/Makefile  |   1 +
 drivers/gpu/drm/i915/dsi_mod_vbt_generic.c | 598 +
 drivers/gpu/drm/i915/intel_drv.h   |   4 +-
 drivers/gpu/drm/i915/intel_dsi.c   |  17 +-
 drivers/gpu/drm/i915/intel_dsi.h   |  15 +-
 5 files changed, 630 insertions(+), 5 deletions(-)
 create mode 100644 drivers/gpu/drm/i915/dsi_mod_vbt_generic.c

-- 
1.8.3.2

___
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/intel-gfx


[Intel-gfx] [PATCH 4/4] drm/i915: Add support for Generic MIPI panel driver

2014-04-13 Thread Shobhit Kumar
This driver makes use of the generic panel information from the VBT.
Panel information is classified into two - panel configuration and panel
power sequence which is unique to each panel. The generic driver uses the
panel configuration and sequence parsed from VBT block #52 and #53

v2: Address review comments by Jani
- Move all of the things in driver c file from header
- Make all functions static
- Make use of video/mipi_display.c instead of redefining
- Null checks during sequence execution

Signed-off-by: Shobhit Kumar 
---
 drivers/gpu/drm/i915/Makefile  |   1 +
 drivers/gpu/drm/i915/dsi_mod_vbt_generic.c | 598 +
 drivers/gpu/drm/i915/intel_dsi.c   |   5 +
 drivers/gpu/drm/i915/intel_dsi.h   |   2 +
 4 files changed, 606 insertions(+)
 create mode 100644 drivers/gpu/drm/i915/dsi_mod_vbt_generic.c

diff --git a/drivers/gpu/drm/i915/Makefile b/drivers/gpu/drm/i915/Makefile
index b1445b7..756a7a4 100644
--- a/drivers/gpu/drm/i915/Makefile
+++ b/drivers/gpu/drm/i915/Makefile
@@ -55,6 +55,7 @@ i915-y += dvo_ch7017.o \
  intel_dsi_cmd.o \
  intel_dsi.o \
  intel_dsi_pll.o \
+ dsi_mod_vbt_generic.o \
  intel_dvo.o \
  intel_hdmi.o \
  intel_i2c.o \
diff --git a/drivers/gpu/drm/i915/dsi_mod_vbt_generic.c 
b/drivers/gpu/drm/i915/dsi_mod_vbt_generic.c
new file mode 100644
index 000..0c12ce8
--- /dev/null
+++ b/drivers/gpu/drm/i915/dsi_mod_vbt_generic.c
@@ -0,0 +1,598 @@
+/*
+ * Copyright © 2014 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.
+ *
+ * Author: Shobhit Kumar 
+ *
+ */
+
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include "i915_drv.h"
+#include "intel_drv.h"
+#include "intel_dsi.h"
+#include "intel_dsi_cmd.h"
+
+#define MIPI_TRANSFER_MODE_SHIFT   0
+#define MIPI_VIRTUAL_CHANNEL_SHIFT 1
+#define MIPI_PORT_SHIFT3
+
+#define PREPARE_CNT_MAX0x3F
+#define EXIT_ZERO_CNT_MAX  0x3F
+#define CLK_ZERO_CNT_MAX   0xFF
+#define TRAIL_CNT_MAX  0x1F
+
+#define NS_MHZ_RATIO 100
+
+/* This macro divides two integers and rounds fractional values up
+ * to the nearest integer value. */
+#define CEIL_DIV(X, Y) (((X)%(Y)) ? ((X)/(Y)+1) : ((X)/(Y)))
+
+#define GPI0_NC_0_HV_DDI0_HPD   0x4130
+#define GPIO_NC_0_HV_DDI0_PAD   0x4138
+#define GPIO_NC_1_HV_DDI0_DDC_SDA   0x4120
+#define GPIO_NC_1_HV_DDI0_DDC_SDA_PAD   0x4128
+#define GPIO_NC_2_HV_DDI0_DDC_SCL   0x4110
+#define GPIO_NC_2_HV_DDI0_DDC_SCL_PAD   0x4118
+#define GPIO_NC_3_PANEL0_VDDEN  0x4140
+#define GPIO_NC_3_PANEL0_VDDEN_PAD  0x4148
+#define GPIO_NC_4_PANEL0_BLKEN  0x4150
+#define GPIO_NC_4_PANEL0_BLKEN_PAD  0x4158
+#define GPIO_NC_5_PANEL0_BLKCTL 0x4160
+#define GPIO_NC_5_PANEL0_BLKCTL_PAD 0x4168
+#define GPIO_NC_6_PCONF00x4180
+#define GPIO_NC_6_PAD   0x4188
+#define GPIO_NC_7_PCONF00x4190
+#define GPIO_NC_7_PAD   0x4198
+#define GPIO_NC_8_PCONF00x4170
+#define GPIO_NC_8_PAD   0x4178
+#define GPIO_NC_9_PCONF00x4100
+#define GPIO_NC_9_PAD   0x4108
+#define GPIO_NC_10_PCONF0   0x40E0
+#define GPIO_NC_10_PAD  0x40E8
+#define GPIO_NC_11_PCONF0   0x40F0
+#define GPIO_NC_11_PAD  0x40F8
+
+struct gpio_table {
+   u16 function_reg;
+   u16 pad_reg;
+   u8 init;
+};
+
+static struct gpio_table gtable[] = {
+   { GPI0_NC_0_HV_DDI0_HPD, GPIO_NC_0_HV_DDI0_PAD, 0 },
+   { GPIO_NC_1_HV_DDI0_DDC_SDA, GPIO_NC_1_HV_DDI0_DDC_SDA_PAD, 0 },
+   { GPIO_NC_2_HV_DDI0_DDC_SCL, GPIO_NC_2_HV_DDI0_DDC_SCL_PAD, 0 },
+  

[Intel-gfx] [PATCH 2/4] drm/i915: MIPI init count programming as generic parameter

2014-04-13 Thread Shobhit Kumar
Signed-off-by: Shobhit Kumar 
---
 drivers/gpu/drm/i915/intel_dsi.c | 3 +++
 drivers/gpu/drm/i915/intel_dsi.h | 2 ++
 2 files changed, 5 insertions(+)

diff --git a/drivers/gpu/drm/i915/intel_dsi.c b/drivers/gpu/drm/i915/intel_dsi.c
index 2795782..09b9318 100644
--- a/drivers/gpu/drm/i915/intel_dsi.c
+++ b/drivers/gpu/drm/i915/intel_dsi.c
@@ -525,6 +525,9 @@ static void intel_dsi_mode_set(struct intel_encoder 
*intel_encoder)
/* recovery disables */
I915_WRITE(MIPI_EOT_DISABLE(pipe), val);
 
+   /* in terms of low power clock */
+   I915_WRITE(MIPI_INIT_COUNT(pipe), intel_dsi->init_count);
+
/* in terms of txbyteclkhs. actual high to low switch +
 * MIPI_STOP_STATE_STALL * MIPI_LP_BYTECLK.
 *
diff --git a/drivers/gpu/drm/i915/intel_dsi.h b/drivers/gpu/drm/i915/intel_dsi.h
index 1649422..be132c5 100644
--- a/drivers/gpu/drm/i915/intel_dsi.h
+++ b/drivers/gpu/drm/i915/intel_dsi.h
@@ -114,6 +114,8 @@ struct intel_dsi {
u16 hs_to_lp_count;
u16 clk_lp_to_hs_count;
u16 clk_hs_to_lp_count;
+
+   u16 init_count;
 };
 
 static inline struct intel_dsi *enc_to_intel_dsi(struct drm_encoder *encoder)
-- 
1.8.3.2

___
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/intel-gfx


[Intel-gfx] [PATCH 1/4] drm/i915: Correct MIPI operation mode as per expected values from VBT

2014-04-13 Thread Shobhit Kumar
In VBT fields operation mode is 0 for Video mode and 1 for command mode.
This field will be directly used as is in generic panel driver. So
adjust accordingly.

Signed-off-by: Shobhit Kumar 
---
 drivers/gpu/drm/i915/intel_drv.h | 4 ++--
 drivers/gpu/drm/i915/intel_dsi.c | 4 ++--
 drivers/gpu/drm/i915/intel_dsi.h | 4 +++-
 3 files changed, 7 insertions(+), 5 deletions(-)

diff --git a/drivers/gpu/drm/i915/intel_drv.h b/drivers/gpu/drm/i915/intel_drv.h
index c551472..fca11f3 100644
--- a/drivers/gpu/drm/i915/intel_drv.h
+++ b/drivers/gpu/drm/i915/intel_drv.h
@@ -106,8 +106,8 @@
 #define INTEL_DVO_CHIP_TMDS 2
 #define INTEL_DVO_CHIP_TVOUT 4
 
-#define INTEL_DSI_COMMAND_MODE 0
-#define INTEL_DSI_VIDEO_MODE   1
+#define INTEL_DSI_VIDEO_MODE   0
+#define INTEL_DSI_COMMAND_MODE 1
 
 struct intel_framebuffer {
struct drm_framebuffer base;
diff --git a/drivers/gpu/drm/i915/intel_dsi.c b/drivers/gpu/drm/i915/intel_dsi.c
index 4e271c7..2795782 100644
--- a/drivers/gpu/drm/i915/intel_dsi.c
+++ b/drivers/gpu/drm/i915/intel_dsi.c
@@ -59,12 +59,12 @@ static struct intel_dsi *intel_attached_dsi(struct 
drm_connector *connector)
 
 static inline bool is_vid_mode(struct intel_dsi *intel_dsi)
 {
-   return intel_dsi->dev.type == INTEL_DSI_VIDEO_MODE;
+   return intel_dsi->operation_mode == INTEL_DSI_VIDEO_MODE;
 }
 
 static inline bool is_cmd_mode(struct intel_dsi *intel_dsi)
 {
-   return intel_dsi->dev.type == INTEL_DSI_COMMAND_MODE;
+   return intel_dsi->operation_mode == INTEL_DSI_COMMAND_MODE;
 }
 
 static void intel_dsi_hot_plug(struct intel_encoder *encoder)
diff --git a/drivers/gpu/drm/i915/intel_dsi.h b/drivers/gpu/drm/i915/intel_dsi.h
index 550714c..1649422 100644
--- a/drivers/gpu/drm/i915/intel_dsi.h
+++ b/drivers/gpu/drm/i915/intel_dsi.h
@@ -31,7 +31,6 @@
 struct intel_dsi_device {
unsigned int panel_id;
const char *name;
-   int type;
const struct intel_dsi_dev_ops *dev_ops;
void *dev_priv;
 };
@@ -85,6 +84,9 @@ struct intel_dsi {
/* virtual channel */
int channel;
 
+   /* Video mode or command mode */
+   u16 operation_mode;
+
/* number of DSI lanes */
unsigned int lane_count;
 
-- 
1.8.3.2

___
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/intel-gfx


[Intel-gfx] [PATCH 3/4] drm/i915: MIPI PPS delays added

2014-04-13 Thread Shobhit Kumar
Added as generic parameters which will be initialized in the panel
driver and are specific to panels.

Backlight delays have also kept as placeholders and will be used used
once we have MIPI backlight enabling support

Signed-off-by: Shobhit Kumar 
---
 drivers/gpu/drm/i915/intel_dsi.c | 5 +
 drivers/gpu/drm/i915/intel_dsi.h | 7 +++
 2 files changed, 12 insertions(+)

diff --git a/drivers/gpu/drm/i915/intel_dsi.c b/drivers/gpu/drm/i915/intel_dsi.c
index 09b9318..0d4dd54 100644
--- a/drivers/gpu/drm/i915/intel_dsi.c
+++ b/drivers/gpu/drm/i915/intel_dsi.c
@@ -185,6 +185,8 @@ static void intel_dsi_pre_enable(struct intel_encoder 
*encoder)
/* put device in ready state */
intel_dsi_device_ready(encoder);
 
+   msleep(intel_dsi->panel_on_delay);
+
if (intel_dsi->dev.dev_ops->panel_reset)
intel_dsi->dev.dev_ops->panel_reset(&intel_dsi->dev);
 
@@ -301,6 +303,9 @@ static void intel_dsi_post_disable(struct intel_encoder 
*encoder)
 
if (intel_dsi->dev.dev_ops->disable_panel_power)
intel_dsi->dev.dev_ops->disable_panel_power(&intel_dsi->dev);
+
+   msleep(intel_dsi->panel_off_delay);
+   msleep(intel_dsi->panel_pwr_cycle_delay);
 }
 
 static bool intel_dsi_get_hw_state(struct intel_encoder *encoder,
diff --git a/drivers/gpu/drm/i915/intel_dsi.h b/drivers/gpu/drm/i915/intel_dsi.h
index be132c5..e3f4e91 100644
--- a/drivers/gpu/drm/i915/intel_dsi.h
+++ b/drivers/gpu/drm/i915/intel_dsi.h
@@ -116,6 +116,13 @@ struct intel_dsi {
u16 clk_hs_to_lp_count;
 
u16 init_count;
+
+   /* all delays in ms */
+   u16 backlight_off_delay;
+   u16 backlight_on_delay;
+   u16 panel_on_delay;
+   u16 panel_off_delay;
+   u16 panel_pwr_cycle_delay;
 };
 
 static inline struct intel_dsi *enc_to_intel_dsi(struct drm_encoder *encoder)
-- 
1.8.3.2

___
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/intel-gfx


[Intel-gfx] [PATCH] drm/i915: Code cleanup patch to fix checkpatch errors

2014-04-15 Thread Shobhit Kumar
This cleans up the checkpatch errors for the merged commit -

commit d3b542fcfc72d7724585e3fd2c5e75351bc3df47
Author: Shobhit Kumar 
Date:   Mon Apr 14 11:00:34 2014 +0530

drm/i915: Add parsing support for new MIPI blocks in VBT

Signed-off-by: Shobhit Kumar 
---
 drivers/gpu/drm/i915/intel_bios.c | 12 
 1 file changed, 8 insertions(+), 4 deletions(-)

diff --git a/drivers/gpu/drm/i915/intel_bios.c 
b/drivers/gpu/drm/i915/intel_bios.c
index 917f5bb..fba9efd 100644
--- a/drivers/gpu/drm/i915/intel_bios.c
+++ b/drivers/gpu/drm/i915/intel_bios.c
@@ -653,13 +653,15 @@ static u8 *goto_next_sequence(u8 *data, int *size)
 * skip by this element payload size
 * skip elem id, command flag and data type
 */
-   if ((tmp = tmp - 5) < 0)
+   tmp -= 5;
+   if (tmp < 0)
return NULL;
 
data += 3;
len = *((u16 *)data);
 
-   if ((tmp = tmp - len) < 0)
+   tmp -= len;
+   if (tmp < 0)
return NULL;
 
/* skip by len */
@@ -667,13 +669,15 @@ static u8 *goto_next_sequence(u8 *data, int *size)
break;
case MIPI_SEQ_ELEM_DELAY:
/* skip by elem id, and delay is 4 bytes */
-   if ((tmp = tmp - 5) < 0)
+   tmp -= 5;
+   if (tmp < 0)
return NULL;
 
data += 5;
break;
case MIPI_SEQ_ELEM_GPIO:
-   if ((tmp = tmp - 3) < 0)
+   tmp -= 3;
+   if (tmp < 0)
return NULL;
 
data += 3;
-- 
1.8.3.2

___
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/intel-gfx


Re: [Intel-gfx] [PATCH 00/66] runtime pm for DPMS

2014-04-30 Thread Shobhit Kumar

   drm/i915: Shovel hw setup code out of i9xx_crtc_mode_set
   drm/i915: Move lowfreq_avail around a bit in ilk/hsw_crtc_mode_set
   drm/i915: Shovel hw setup code out of ilk_crtc_mode_set
   drm/i915: Shovel hw setup code out of hsw_crtc_mode_set
   drm/i915: Extract i9xx_set_pll_dividers
   drm/i915: Extract vlv_prepare_pll

gmch pll moved out of crtc mode_set callbacks into ->enable hooks


Reviewer: Shobhit Kumar


I will be on vacation till next weekend, so will get to these after 
that. Keep on my name if that is okay.


Regards
Shobhit
___
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/intel-gfx


Re: [Intel-gfx] [PATCH 4/4] drm/i915: Add support for Generic MIPI panel driver

2014-05-16 Thread Shobhit Kumar

Thanks Damien for your review

On Thursday 15 May 2014 10:18 PM, Damien Lespiau wrote:

On Mon, Apr 14, 2014 at 11:18:27AM +0530, Shobhit Kumar wrote:

>This driver makes use of the generic panel information from the VBT.
>Panel information is classified into two - panel configuration and panel
>power sequence which is unique to each panel. The generic driver uses the
>panel configuration and sequence parsed from VBT block #52 and #53
>
>v2: Address review comments by Jani
> - Move all of the things in driver c file from header
> - Make all functions static
> - Make use of video/mipi_display.c instead of redefining
> - Null checks during sequence execution
>
>Signed-off-by: Shobhit Kumar

I've done a first past on this. Overall looks reasonable. I'm missing
some documentation to double check the various LP->HS, HS->LP count and
other magic around the clocks (send you a mail about it) before I can
add my r-b tag.

I've added a few tiny comments as well along the road.


All look okay to me and Will push updated patch asap.

There is one issue which I am struggling for now. If we have all these 
patches in, then disable sequence pipe off does not work and 
wait_for_pipe_off gives a warn dump but everything works. Its not this 
patch issue but DSI patches that are already merged. I know the fix is 
to actually disable port after disabling pipe and plane but doing that 
does not succeed enable in first attempt. Subsequent disable/enable 
works. Looking into that and should have a fix by next week on that.


Regards
Shobhit
___
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/intel-gfx


Re: [Intel-gfx] [PATCH 4/4] drm/i915: Add support for Generic MIPI panel driver

2014-05-20 Thread Shobhit Kumar

On Monday 19 May 2014 07:53 PM, Damien Lespiau wrote:

On Mon, Apr 14, 2014 at 11:18:27AM +0530, Shobhit Kumar wrote:

+#define NS_MHZ_RATIO 100


[...]


+static bool generic_init(struct intel_dsi_device *dsi)
+{


[...]


+   /*
+* ui(s) = 1/f [f in hz]
+* ui(ns) = 10^9/f*10^6 [f in Mhz] -> 10^3/f(Mhz)


ui(ns) = 10^9/(f*10^6)


+*
+* LP byte clock = TLPX/8ui


Mind putting that comment just above the appropriate computation?
Also, LP byte clock = Tlpx / (8UI)


+*
+* Since txddrclkhs_i is 2xUI, the count values programmed in
+* DPHY param registers are divided by 2


That looks like a general comment that apply to a bunch of calculations
below, probably worth separating it from the UI comment.



Will update as suggested.


+*
+*/
+
+   /* in Kbps */
+   ui_num = bitrate;
+   ui_den = NS_MHZ_RATIO;


I'm a bit confused here, most likely missing something, care to clarify?

- IIUC, you want the computations to happen in ns. I'm a bit puzzled by
   that NS_MHZ_RATIO constant name when we're dealing with Kbps.

   That constant is 10^6 which seems to be OK for KHz. So maybe just a
   naming problem?


Yeah, I now realize that it should be something like NS_KHZ_RATIO to 
avoid confusion




- UI is a period, so is homogeneous to time (s), but ui_num being in
   s^-1 and ui_den a constant, ui_num/ui_den looks like a frequency. Or
   could it be that UI = ui_den / ui_num? would be confusing, but the
   code below would make more sense. In which case could we have UI =
   ui_num / ui_den?


I just kept ui_num and ui_den separately to take care of precision loss, 
but I see how it is adding to confusion. Actually it is ui_den / ui_num 
and we have all computations as 1/UI so it works. I think I will compute 
UI directly as UI = (NS_KHZ_RATIO * 1000) /bitrate and divide by 1000 
wherever we use to maintain precision. Sounds ok ?





+
+   tclk_prepare_clkzero = mipi_config->tclk_prepare_clkzero;
+   ths_prepare_hszero = mipi_config->ths_prepare_hszero;
+
+   /* B060 */
+   intel_dsi->lp_byte_clk = CEIL_DIV(tlpx_ns * ui_num, 8 * ui_den);
+
+   /* count values in UI = (ns value) * (bitrate / (2 * 10^6)) */
+   /* prepare count */
+   ths_prepare_ns =
+   (mipi_config->ths_prepare >  mipi_config->tclk_prepare) ?
+   mipi_config->ths_prepare :
+   mipi_config->tclk_prepare;


That looks like max()


+
+   prepare_cnt = CEIL_DIV(ths_prepare_ns * ui_num, ui_den * 2);


The formula above has a 10^6, why is that OK not to have it there? (in
which unit is bitrate in the formula? MHz?) Is this something like:

   Count in UI = count(ns) / UI(ns)

and then as UI = ui_den/ui_num (?!) we end up with:

   Count in UI = count(ns) * ui_num / ui_den

And then the / 2 comment applies.


Yeah actually its like this. I will correct as suggested above.




+
+   /* exit zero count */
+   exit_zero_cnt = CEIL_DIV(
+   (ths_prepare_hszero - ths_prepare_ns) * ui_num,
+   ui_den * 2
+   );
+
+   /*
+* Exit zero  is unified val ths_zero and ths_exit
+* minimum value for ths_exit = 110ns
+* min (exit_zero_cnt * 2) = 110/UI
+* exit_zero_cnt = 55/UI
+*/
+if (exit_zero_cnt < (55 * ui_num / ui_den))
+   if ((55 * ui_num) % ui_den)
+   exit_zero_cnt += 1;


I'm not sure what we're achieving with the +=1 here, mind explaining?


This is as per MIPI host controller spec to ceil the value




+
+   /* clk zero count */
+   clk_zero_cnt = CEIL_DIV(
+   (tclk_prepare_clkzero - ths_prepare_ns)
+   * ui_num, 2 * ui_den);
+
+   /* trail count */
+   tclk_trail_ns = (mipi_config->tclk_trail > mipi_config->ths_trail) ?
+   mipi_config->tclk_trail : mipi_config->ths_trail;


max()


+   trail_cnt = CEIL_DIV(tclk_trail_ns * ui_num, 2 * ui_den);
+
+   if (prepare_cnt > PREPARE_CNT_MAX ||
+   exit_zero_cnt > EXIT_ZERO_CNT_MAX ||
+   clk_zero_cnt > CLK_ZERO_CNT_MAX ||
+   trail_cnt > TRAIL_CNT_MAX)
+   DRM_DEBUG_DRIVER("Values crossing maximum limits\n");


Is that a situation that may happen in a normal case? or should we go
with a DRM_ERROR() here and potentially abort the modeset?



Generally it should not happen. We should not abort but clip to max 
values though there is no guarantee it will work, but there is high 
chance that it will work.



+
+   if (prepare_cnt > PREPARE_CNT_MAX)
+   prepare_cnt = PREPARE_CNT_MAX;
+
+   if (exit_zero_cnt > EXIT_ZERO_CNT_MAX)
+   exit_zero_cnt = EXIT_ZERO_CNT_MAX;
+
+   if (clk_zer

[Intel-gfx] [v2] drm/i915: Add support for Generic MIPI panel driver

2014-05-23 Thread Shobhit Kumar
This driver makes use of the generic panel information from the VBT.
Panel information is classified into two - panel configuration and panel
power sequence which is unique to each panel. The generic driver uses the
panel configuration and sequence parsed from VBT block #52 and #53

v2: Address review comments by Jani
- Move all of the things in driver c file from header
- Make all functions static
- Make use of video/mipi_display.c instead of redefining
- Null checks during sequence execution

v3: Address review comments by Damien
- Rename the panel driver file as intel_dsi_panel_vbt.c
- Fix style changes as suggested
- Correct comments for lp->hs and hs->lp count calculations
- General updating comments to have more clarity
- using max() instead of ternary operator
- Fix names (ui_num, ui_den) while using UI in calculations
- compute max of lp_to_hs switch and hs_to_lp switch while computing
  hs_lp_switch_count

Signed-off-by: Shobhit Kumar 
---
 drivers/gpu/drm/i915/Makefile  |   1 +
 drivers/gpu/drm/i915/intel_dsi.c   |   5 +
 drivers/gpu/drm/i915/intel_dsi.h   |   2 +
 drivers/gpu/drm/i915/intel_dsi_panel_vbt.c | 589 +
 4 files changed, 597 insertions(+)
 create mode 100644 drivers/gpu/drm/i915/intel_dsi_panel_vbt.c

diff --git a/drivers/gpu/drm/i915/Makefile b/drivers/gpu/drm/i915/Makefile
index 7b2f3be..cad1683 100644
--- a/drivers/gpu/drm/i915/Makefile
+++ b/drivers/gpu/drm/i915/Makefile
@@ -62,6 +62,7 @@ i915-y += dvo_ch7017.o \
  intel_dsi_cmd.o \
  intel_dsi.o \
  intel_dsi_pll.o \
+ intel_dsi_panel_vbt.o \
  intel_dvo.o \
  intel_hdmi.o \
  intel_i2c.o \
diff --git a/drivers/gpu/drm/i915/intel_dsi.c b/drivers/gpu/drm/i915/intel_dsi.c
index 2525cdd..e73bec6 100644
--- a/drivers/gpu/drm/i915/intel_dsi.c
+++ b/drivers/gpu/drm/i915/intel_dsi.c
@@ -35,6 +35,11 @@
 
 /* the sub-encoders aka panel drivers */
 static const struct intel_dsi_device intel_dsi_devices[] = {
+   {
+   .panel_id = MIPI_DSI_GENERIC_PANEL_ID,
+   .name = "vbt-generic-dsi-vid-mode-display",
+   .dev_ops = &vbt_generic_dsi_display_ops,
+   },
 };
 
 static void band_gap_reset(struct drm_i915_private *dev_priv)
diff --git a/drivers/gpu/drm/i915/intel_dsi.h b/drivers/gpu/drm/i915/intel_dsi.h
index e3f4e91..31db33d 100644
--- a/drivers/gpu/drm/i915/intel_dsi.h
+++ b/drivers/gpu/drm/i915/intel_dsi.h
@@ -133,4 +133,6 @@ static inline struct intel_dsi *enc_to_intel_dsi(struct 
drm_encoder *encoder)
 extern void vlv_enable_dsi_pll(struct intel_encoder *encoder);
 extern void vlv_disable_dsi_pll(struct intel_encoder *encoder);
 
+extern struct intel_dsi_dev_ops vbt_generic_dsi_display_ops;
+
 #endif /* _INTEL_DSI_H */
diff --git a/drivers/gpu/drm/i915/intel_dsi_panel_vbt.c 
b/drivers/gpu/drm/i915/intel_dsi_panel_vbt.c
new file mode 100644
index 000..21a0d34
--- /dev/null
+++ b/drivers/gpu/drm/i915/intel_dsi_panel_vbt.c
@@ -0,0 +1,589 @@
+/*
+ * Copyright © 2014 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.
+ *
+ * Author: Shobhit Kumar 
+ *
+ */
+
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include "i915_drv.h"
+#include "intel_drv.h"
+#include "intel_dsi.h"
+#include "intel_dsi_cmd.h"
+
+#define MIPI_TRANSFER_MODE_SHIFT   0
+#define MIPI_VIRTUAL_CHANNEL_SHIFT 1
+#define MIPI_PORT_SHIFT3
+
+#define PREPARE_CNT_MAX0x3F
+#define EXIT_ZERO_CNT_MAX  0x3F
+#define CLK_ZERO_CNT_MAX   0xFF
+#define TRAIL_CNT_MAX  0x1F
+
+#define NS_KHZ_RATIO 100
+
+#define GPI0_NC_0_HV_DDI0_HPD   0x4130
+#define GPIO_NC_0_HV_DDI0_PAD   0x4138
+#define GPIO_NC_1_HV_DD

[Intel-gfx] [PATCH] drm/i915: Detect if MIPI panel based on VBT and initialize only if present

2014-05-23 Thread Shobhit Kumar
It seems by default the VBT has MIPI configuration block as well. The
Generic driver will assume always MIPI if MIPI configuration block is found.
This is causing probelm when actually there is eDP. Fix this by looking
into general definition block which will have device configurations. From here
we can figure out what is the LFP type and initialize MIPI only if MIPI
is found.

Signed-off-by: Shobhit Kumar 
---
 drivers/gpu/drm/i915/i915_drv.h  |  2 ++
 drivers/gpu/drm/i915/intel_bios.c| 20 +++-
 drivers/gpu/drm/i915/intel_display.c |  4 +++-
 3 files changed, 24 insertions(+), 2 deletions(-)

diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h
index 8e78703..5a5225b 100644
--- a/drivers/gpu/drm/i915/i915_drv.h
+++ b/drivers/gpu/drm/i915/i915_drv.h
@@ -1229,7 +1229,9 @@ struct intel_vbt_data {
} backlight;
 
/* MIPI DSI */
+   int is_mipi;
struct {
+   u16 port;
u16 panel_id;
struct mipi_config *config;
struct mipi_pps_data *pps;
diff --git a/drivers/gpu/drm/i915/intel_bios.c 
b/drivers/gpu/drm/i915/intel_bios.c
index 6b65096..b825c80 100644
--- a/drivers/gpu/drm/i915/intel_bios.c
+++ b/drivers/gpu/drm/i915/intel_bios.c
@@ -1059,6 +1059,20 @@ parse_device_mapping(struct drm_i915_private *dev_priv,
/* skip the device block if device type is invalid */
continue;
}
+
+#define MIPI_PORT_A0x15
+#define MIPI_PORT_B0x16
+#define MIPI_PORT_C0x17
+#define MIPI_PORT_D0x18
+   if (p_child->common.dvo_port >= MIPI_PORT_A && 
p_child->common.dvo_port <= MIPI_PORT_D) {
+   /* check the device type and confirm its MIPI */
+   if (p_child->common.device_type & 
DEVICE_TYPE_MIPI_OUTPUT) {
+   DRM_DEBUG_KMS("Found MIPI as LFP\n");
+   dev_priv->vbt.is_mipi = 1;
+   dev_priv->vbt.dsi.port = 
p_child->common.dvo_port;
+   }
+   }
+
child_dev_ptr = dev_priv->vbt.child_dev + count;
count++;
memcpy((void *)child_dev_ptr, (void *)p_child,
@@ -1230,7 +1244,11 @@ intel_parse_bios(struct drm_device *dev)
parse_device_mapping(dev_priv, bdb);
parse_driver_features(dev_priv, bdb);
parse_edp(dev_priv, bdb);
-   parse_mipi(dev_priv, bdb);
+
+   /* parse MIPI blocks only if LFP type is MIPI */
+   if (dev_priv->vbt.is_mipi)
+   parse_mipi(dev_priv, bdb);
+
parse_ddi_ports(dev_priv, bdb);
 
if (bios)
diff --git a/drivers/gpu/drm/i915/intel_display.c 
b/drivers/gpu/drm/i915/intel_display.c
index 3da73ef..a55fa41 100644
--- a/drivers/gpu/drm/i915/intel_display.c
+++ b/drivers/gpu/drm/i915/intel_display.c
@@ -11151,7 +11151,9 @@ static void intel_setup_outputs(struct drm_device *dev)
}
}
 
-   intel_dsi_init(dev);
+   /* There is no detection method for MIPI so rely on VBT */
+   if (dev_priv->vbt.is_mipi)
+   intel_dsi_init(dev);
} else if (SUPPORTS_DIGITAL_OUTPUTS(dev)) {
bool found = false;
 
-- 
1.8.3.2

___
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/intel-gfx


[Intel-gfx] [v2] drm/i915: Detect if MIPI panel based on VBT and initialize only if present

2014-05-27 Thread Shobhit Kumar
It seems by default the VBT has MIPI configuration block as well. The
Generic driver will assume always MIPI if MIPI configuration block is found.
This is causing probelm when actually there is eDP. Fix this by looking
into general definition block which will have device configurations. From here
we can figure out what is the LFP type and initialize MIPI only if MIPI
is found.

v2: Addressed review comments by Damien
- Moved PORT definitions to intel_bios.h and renamed as DVO_PORT_MIPIA
- renamed is_mipi to has_mipi and moved definition as suggested
- Check hs_mipi inside parse_mipi and intel_dsi_init insted of outside

Signed-off-by: Shobhit Kumar 
---
 drivers/gpu/drm/i915/i915_drv.h   |  2 ++
 drivers/gpu/drm/i915/intel_bios.c | 14 ++
 drivers/gpu/drm/i915/intel_bios.h |  4 
 drivers/gpu/drm/i915/intel_dsi.c  |  4 
 4 files changed, 24 insertions(+)

diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h
index 8e78703..dac9ceb 100644
--- a/drivers/gpu/drm/i915/i915_drv.h
+++ b/drivers/gpu/drm/i915/i915_drv.h
@@ -1209,6 +1209,7 @@ struct intel_vbt_data {
unsigned int fdi_rx_polarity_inverted:1;
int lvds_ssc_freq;
unsigned int bios_lvds_val; /* initial [PCH_]LVDS reg val in VBIOS */
+   int has_mipi;
 
enum drrs_support_type drrs_type;
 
@@ -1230,6 +1231,7 @@ struct intel_vbt_data {
 
/* MIPI DSI */
struct {
+   u16 port;
u16 panel_id;
struct mipi_config *config;
struct mipi_pps_data *pps;
diff --git a/drivers/gpu/drm/i915/intel_bios.c 
b/drivers/gpu/drm/i915/intel_bios.c
index 6b65096..6f6b6c6 100644
--- a/drivers/gpu/drm/i915/intel_bios.c
+++ b/drivers/gpu/drm/i915/intel_bios.c
@@ -744,6 +744,10 @@ parse_mipi(struct drm_i915_private *dev_priv, struct 
bdb_header *bdb)
int i, panel_id, seq_size;
u16 block_size;
 
+   /* parse MIPI blocks only if LFP type is MIPI */
+   if (!dev_priv->vbt.has_mipi)
+   return;
+
/* Initialize this to undefined indicating no generic MIPI support */
dev_priv->vbt.dsi.panel_id = MIPI_DSI_UNDEFINED_PANEL_ID;
 
@@ -1059,6 +1063,16 @@ parse_device_mapping(struct drm_i915_private *dev_priv,
/* skip the device block if device type is invalid */
continue;
}
+
+   if (p_child->common.dvo_port >= DVO_PORT_MIPIA && 
p_child->common.dvo_port <= DVO_PORT_MIPID) {
+   /* check the device type and confirm its MIPI */
+   if (p_child->common.device_type & 
DEVICE_TYPE_MIPI_OUTPUT) {
+   DRM_DEBUG_KMS("Found MIPI as LFP\n");
+   dev_priv->vbt.has_mipi = 1;
+   dev_priv->vbt.dsi.port = 
p_child->common.dvo_port;
+   }
+   }
+
child_dev_ptr = dev_priv->vbt.child_dev + count;
count++;
memcpy((void *)child_dev_ptr, (void *)p_child,
diff --git a/drivers/gpu/drm/i915/intel_bios.h 
b/drivers/gpu/drm/i915/intel_bios.h
index 6009deb..b986677 100644
--- a/drivers/gpu/drm/i915/intel_bios.h
+++ b/drivers/gpu/drm/i915/intel_bios.h
@@ -743,6 +743,10 @@ int intel_parse_bios(struct drm_device *dev);
 #define DVO_PORT_DPC   8
 #define DVO_PORT_DPD   9
 #define DVO_PORT_DPA   10
+#define DVO_PORT_MIPIA 21
+#define DVO_PORT_MIPIB 22
+#define DVO_PORT_MIPIC 23
+#define DVO_PORT_MIPID 24
 
 /* Block 52 contains MIPI Panel info
  * 6 such enteries will there. Index into correct
diff --git a/drivers/gpu/drm/i915/intel_dsi.c b/drivers/gpu/drm/i915/intel_dsi.c
index e73bec6..944a421 100644
--- a/drivers/gpu/drm/i915/intel_dsi.c
+++ b/drivers/gpu/drm/i915/intel_dsi.c
@@ -660,6 +660,10 @@ bool intel_dsi_init(struct drm_device *dev)
 
DRM_DEBUG_KMS("\n");
 
+   /* There is no detection method for MIPI so rely on VBT */
+   if (!dev_priv->vbt.has_mipi)
+   return false;
+
intel_dsi = kzalloc(sizeof(*intel_dsi), GFP_KERNEL);
if (!intel_dsi)
return false;
-- 
1.8.3.2

___
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/intel-gfx


[Intel-gfx] [PATCH] drm/i915: Fix checkpatch errors

2014-05-27 Thread Shobhit Kumar
Fix warnings introduced by the following commit -

commit 9c92da2c7c17eea79b6321b37592df0a002d24df
Author: Shobhit Kumar 
Date:   Fri May 23 21:35:27 2014 +0530

drm/i915: Add support for Generic MIPI panel driver

Fixed all except the DRM logging which go beyond line 80

Signed-off-by: Shobhit Kumar 
---
 drivers/gpu/drm/i915/intel_dsi_panel_vbt.c | 8 +---
 1 file changed, 5 insertions(+), 3 deletions(-)

diff --git a/drivers/gpu/drm/i915/intel_dsi_panel_vbt.c 
b/drivers/gpu/drm/i915/intel_dsi_panel_vbt.c
index 21a0d34..47c7584 100644
--- a/drivers/gpu/drm/i915/intel_dsi_panel_vbt.c
+++ b/drivers/gpu/drm/i915/intel_dsi_panel_vbt.c
@@ -143,7 +143,7 @@ static u8 *mipi_exec_send_packet(struct intel_dsi 
*intel_dsi, u8 *data)
case MIPI_DSI_DCS_LONG_WRITE:
dsi_vc_dcs_write(intel_dsi, vc, data, len);
break;
-   };
+   }
 
data += len;
 
@@ -294,7 +294,8 @@ static bool generic_init(struct intel_dsi_device *dsi)
intel_dsi->rst_timer_val = mipi_config->device_reset_timer;
intel_dsi->init_count = mipi_config->master_init_timer;
intel_dsi->bw_timer = mipi_config->dbi_bw_timer;
-   intel_dsi->video_frmt_cfg_bits = mipi_config->bta_enabled ? 
DISABLE_VIDEO_BTA : 0;
+   intel_dsi->video_frmt_cfg_bits =
+   mipi_config->bta_enabled ? DISABLE_VIDEO_BTA : 0;
 
switch (intel_dsi->escape_clk_div) {
case 0:
@@ -351,7 +352,8 @@ static bool generic_init(struct intel_dsi_device *dsi)
 *
 * prepare count
 */
-   ths_prepare_ns = max(mipi_config->ths_prepare, 
mipi_config->tclk_prepare);
+   ths_prepare_ns = max(mipi_config->ths_prepare,
+mipi_config->tclk_prepare);
prepare_cnt = DIV_ROUND_UP(ths_prepare_ns * ui_den, ui_num * 2);
 
/* exit zero count */
-- 
1.8.3.2

___
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/intel-gfx


[Intel-gfx] [v3] drm/i915: Detect if MIPI panel based on VBT and initialize only if present

2014-05-27 Thread Shobhit Kumar
It seems by default the VBT has MIPI configuration block as well. The
Generic driver will assume always MIPI if MIPI configuration block is found.
This is causing probelm when actually there is eDP. Fix this by looking
into general definition block which will have device configurations. From here
we can figure out what is the LFP type and initialize MIPI only if MIPI
is found.

v2: Addressed review comments by Damien
- Moved PORT definitions to intel_bios.h and renamed as DVO_PORT_MIPIA
- renamed is_mipi to has_mipi and moved definition as suggested
- Check has_mipi inside parse_mipi and intel_dsi_init insted of outside

v3: Make has_mipi as a bitfield as suggested

Signed-off-by: Shobhit Kumar 
Reviewed-by: Damien Lespiau 
---
 drivers/gpu/drm/i915/i915_drv.h   |  2 ++
 drivers/gpu/drm/i915/intel_bios.c | 14 ++
 drivers/gpu/drm/i915/intel_bios.h |  4 
 drivers/gpu/drm/i915/intel_dsi.c  |  4 
 4 files changed, 24 insertions(+)

diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h
index 9ef6712..ef7ab0a 100644
--- a/drivers/gpu/drm/i915/i915_drv.h
+++ b/drivers/gpu/drm/i915/i915_drv.h
@@ -1208,6 +1208,7 @@ struct intel_vbt_data {
unsigned int lvds_use_ssc:1;
unsigned int display_clock_mode:1;
unsigned int fdi_rx_polarity_inverted:1;
+   unsigned int has_mipi:1;
int lvds_ssc_freq;
unsigned int bios_lvds_val; /* initial [PCH_]LVDS reg val in VBIOS */
 
@@ -1231,6 +1232,7 @@ struct intel_vbt_data {
 
/* MIPI DSI */
struct {
+   u16 port;
u16 panel_id;
struct mipi_config *config;
struct mipi_pps_data *pps;
diff --git a/drivers/gpu/drm/i915/intel_bios.c 
b/drivers/gpu/drm/i915/intel_bios.c
index 6b65096..6f6b6c6 100644
--- a/drivers/gpu/drm/i915/intel_bios.c
+++ b/drivers/gpu/drm/i915/intel_bios.c
@@ -744,6 +744,10 @@ parse_mipi(struct drm_i915_private *dev_priv, struct 
bdb_header *bdb)
int i, panel_id, seq_size;
u16 block_size;
 
+   /* parse MIPI blocks only if LFP type is MIPI */
+   if (!dev_priv->vbt.has_mipi)
+   return;
+
/* Initialize this to undefined indicating no generic MIPI support */
dev_priv->vbt.dsi.panel_id = MIPI_DSI_UNDEFINED_PANEL_ID;
 
@@ -1059,6 +1063,16 @@ parse_device_mapping(struct drm_i915_private *dev_priv,
/* skip the device block if device type is invalid */
continue;
}
+
+   if (p_child->common.dvo_port >= DVO_PORT_MIPIA && 
p_child->common.dvo_port <= DVO_PORT_MIPID) {
+   /* check the device type and confirm its MIPI */
+   if (p_child->common.device_type & 
DEVICE_TYPE_MIPI_OUTPUT) {
+   DRM_DEBUG_KMS("Found MIPI as LFP\n");
+   dev_priv->vbt.has_mipi = 1;
+   dev_priv->vbt.dsi.port = 
p_child->common.dvo_port;
+   }
+   }
+
child_dev_ptr = dev_priv->vbt.child_dev + count;
count++;
memcpy((void *)child_dev_ptr, (void *)p_child,
diff --git a/drivers/gpu/drm/i915/intel_bios.h 
b/drivers/gpu/drm/i915/intel_bios.h
index 6009deb..b986677 100644
--- a/drivers/gpu/drm/i915/intel_bios.h
+++ b/drivers/gpu/drm/i915/intel_bios.h
@@ -743,6 +743,10 @@ int intel_parse_bios(struct drm_device *dev);
 #define DVO_PORT_DPC   8
 #define DVO_PORT_DPD   9
 #define DVO_PORT_DPA   10
+#define DVO_PORT_MIPIA 21
+#define DVO_PORT_MIPIB 22
+#define DVO_PORT_MIPIC 23
+#define DVO_PORT_MIPID 24
 
 /* Block 52 contains MIPI Panel info
  * 6 such enteries will there. Index into correct
diff --git a/drivers/gpu/drm/i915/intel_dsi.c b/drivers/gpu/drm/i915/intel_dsi.c
index e73bec6..944a421 100644
--- a/drivers/gpu/drm/i915/intel_dsi.c
+++ b/drivers/gpu/drm/i915/intel_dsi.c
@@ -660,6 +660,10 @@ bool intel_dsi_init(struct drm_device *dev)
 
DRM_DEBUG_KMS("\n");
 
+   /* There is no detection method for MIPI so rely on VBT */
+   if (!dev_priv->vbt.has_mipi)
+   return false;
+
intel_dsi = kzalloc(sizeof(*intel_dsi), GFP_KERNEL);
if (!intel_dsi)
return false;
-- 
1.8.3.2

___
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/intel-gfx


[Intel-gfx] [PATCH] drm/i915: Update bits to check in device class from VBT to detect eDP

2014-06-05 Thread Shobhit Kumar
The DEVICE_TYPE_eDP has been changed to 0x1806 in case of BYT which
can causes wrong detection failures for eDP. Reduce the number of bits
of interest in DEVICE_TYPE_eDP_BITS to just check most relevant and
conclusive ones and ensure they are set in device_class from VBT. This
will ensure that eDP detection works across platforms

Signed-off-by: Shobhit Kumar 
---
 drivers/gpu/drm/i915/intel_bios.h | 10 +-
 drivers/gpu/drm/i915/intel_dp.c   |  4 ++--
 2 files changed, 3 insertions(+), 11 deletions(-)

diff --git a/drivers/gpu/drm/i915/intel_bios.h 
b/drivers/gpu/drm/i915/intel_bios.h
index b986677..30d02b7 100644
--- a/drivers/gpu/drm/i915/intel_bios.h
+++ b/drivers/gpu/drm/i915/intel_bios.h
@@ -710,16 +710,8 @@ int intel_parse_bios(struct drm_device *dev);
  */
 #define DEVICE_TYPE_eDP_BITS \
(DEVICE_TYPE_INTERNAL_CONNECTOR | \
-DEVICE_TYPE_NOT_HDMI_OUTPUT | \
-DEVICE_TYPE_MIPI_OUTPUT | \
-DEVICE_TYPE_COMPOSITE_OUTPUT | \
-DEVICE_TYPE_DUAL_CHANNEL | \
-DEVICE_TYPE_LVDS_SINGALING | \
-DEVICE_TYPE_TMDS_DVI_SIGNALING | \
-DEVICE_TYPE_VIDEO_SIGNALING | \
 DEVICE_TYPE_DISPLAYPORT_OUTPUT | \
-DEVICE_TYPE_DIGITAL_OUTPUT | \
-DEVICE_TYPE_ANALOG_OUTPUT)
+DEVICE_TYPE_DIGITAL_OUTPUT)
 
 /* define the DVO port for HDMI output type */
 #defineDVO_B   1
diff --git a/drivers/gpu/drm/i915/intel_dp.c b/drivers/gpu/drm/i915/intel_dp.c
index dad3780..68f7380 100644
--- a/drivers/gpu/drm/i915/intel_dp.c
+++ b/drivers/gpu/drm/i915/intel_dp.c
@@ -3842,8 +3842,8 @@ bool intel_dp_is_edp(struct drm_device *dev, enum port 
port)
p_child = dev_priv->vbt.child_dev + i;
 
if (p_child->common.dvo_port == port_mapping[port] &&
-   (p_child->common.device_type & DEVICE_TYPE_eDP_BITS) ==
-   (DEVICE_TYPE_eDP & DEVICE_TYPE_eDP_BITS))
+   ((p_child->common.device_type & DEVICE_TYPE_eDP_BITS) ==
+DEVICE_TYPE_eDP_BITS))
return true;
}
return false;
-- 
1.9.1

___
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/intel-gfx


[Intel-gfx] [PATCH 1/2] drm/i915: Update VBT data structures to have MIPI block enhancements

2014-02-12 Thread Shobhit Kumar
MIPI Block #52 which provides configuration details for the MIPI panel
including dphy settings as per panel and tcon specs

Block #53 gives information on panel enable sequences

Signed-off-by: Shobhit Kumar 
---
 drivers/gpu/drm/i915/intel_bios.c |   5 +-
 drivers/gpu/drm/i915/intel_bios.h | 152 +++---
 drivers/gpu/drm/i915/intel_dsi.h  |   2 +
 3 files changed, 130 insertions(+), 29 deletions(-)

diff --git a/drivers/gpu/drm/i915/intel_bios.c 
b/drivers/gpu/drm/i915/intel_bios.c
index 86b95ca..cf0b25d 100644
--- a/drivers/gpu/drm/i915/intel_bios.c
+++ b/drivers/gpu/drm/i915/intel_bios.c
@@ -30,6 +30,7 @@
 #include 
 #include "i915_drv.h"
 #include "intel_bios.h"
+#include "intel_dsi.h"
 
 #defineSLAVE_ADDR1 0x70
 #defineSLAVE_ADDR2 0x72
@@ -599,14 +600,14 @@ parse_mipi(struct drm_i915_private *dev_priv, struct 
bdb_header *bdb)
 {
struct bdb_mipi *mipi;
 
-   mipi = find_section(bdb, BDB_MIPI);
+   mipi = find_section(bdb, BDB_MIPI_CONFIG);
if (!mipi) {
DRM_DEBUG_KMS("No MIPI BDB found");
return;
}
 
/* XXX: add more info */
-   dev_priv->vbt.dsi.panel_id = mipi->panel_id;
+   dev_priv->vbt.dsi.panel_id = MIPI_DSI_GENERIC_PANEL_ID;
 }
 
 static void parse_ddi_port(struct drm_i915_private *dev_priv, enum port port,
diff --git a/drivers/gpu/drm/i915/intel_bios.h 
b/drivers/gpu/drm/i915/intel_bios.h
index 282de5e..8345e0e 100644
--- a/drivers/gpu/drm/i915/intel_bios.h
+++ b/drivers/gpu/drm/i915/intel_bios.h
@@ -104,7 +104,8 @@ struct vbios_data {
 #define BDB_LVDS_LFP_DATA   42
 #define BDB_LVDS_BACKLIGHT  43
 #define BDB_LVDS_POWER  44
-#define BDB_MIPI50
+#define BDB_MIPI_CONFIG 52
+#define BDB_MIPI_SEQUENCE   53
 #define BDB_SKIP   254 /* VBIOS private block, ignore */
 
 struct bdb_general_features {
@@ -711,44 +712,141 @@ int intel_parse_bios(struct drm_device *dev);
 #define DVO_PORT_DPD   9
 #define DVO_PORT_DPA   10
 
-/* MIPI DSI panel info */
-struct bdb_mipi {
+/* Block 52 contains MIPI Panel info
+ * 6 such enteries will there. Index into correct
+ * entery is based on the panel_index in #40 LFP
+ */
+#define MAX_MIPI_CONFIGURATIONS6
+struct mipi_config {
u16 panel_id;
-   u16 bridge_revision;
 
-   /* General params */
+   /* General Params */
u32 dithering:1;
-   u32 bpp_pixel_format:1;
u32 rsvd1:1;
-   u32 dphy_valid:1;
-   u32 resvd2:28;
-
-   u16 port_info;
-   u16 rsvd3:2;
-   u16 num_lanes:2;
-   u16 rsvd4:12;
-
-   /* DSI config */
-   u16 virt_ch_num:2;
-   u16 vtm:2;
-   u16 rsvd5:12;
+   u32 panel_type:1;
+   u32 panel_arch_type:2;
+   u32 cmd_mode:1;
+   u32 vtm:2;
+   u32 cabc:1;
+   u32 pwm_blc:1;
+
+   /* Bit 13:10
+* 000 - Reserved, 001 - RGB565, 002 - RGB666,
+* 011 - RGB666Loosely packed, 100 - RGB888,
+* others - rsvd
+*/
+   u32 videomode_color_format:4;
 
-   u32 dsi_clock;
+   /* Bit 15:14
+* 0 - No rotation, 1 - 90 degree
+* 2 - 180 degree, 3 - 270 degree
+*/
+   u32 rotation:2;
+   u32 bta:1;
+   u32 rsvd2:15;
+
+   /* 2 byte Port Description */
+   u16 dual_link:2;
+   u16 lane_cnt:2;
+   u16 rsvd3:12;
+
+   /* 2 byte DSI COntroller params */
+   /* 0 - Using DSI PHY, 1 - TE usage */
+   u16 dsi_usage:1;
+   u16 rsvd4:15;
+
+   u8 rsvd5[5];
+   u32 dsi_ddr_clk;
u32 bridge_ref_clk;
-   u16 rsvd_pwr;
 
-   /* Dphy Params */
-   u32 prepare_cnt:5;
-   u32 rsvd6:3;
+   u8 byte_clk_sel:2;
+   u8 rsvd6:6;
+
+   /* DPHY Flags */
+   u16 dphy_param_valid:1;
+   u16 eot_disabled:1;
+   u16 clk_stop:1;
+   u16 rsvd7:13;
+
+   u32 hs_tx_timeout;
+   u32 lp_rx_timeout;
+   u32 turn_around_timeout;
+   u32 device_reset_timer;
+   u32 master_init_timer;
+   u32 dbi_bw_timer;
+   u32 lp_byte_clk_val;
+
+   /*  4 byte Dphy Params */
+   u32 prepare_cnt:6;
+   u32 rsvd8:2;
u32 clk_zero_cnt:8;
u32 trail_cnt:5;
-   u32 rsvd7:3;
+   u32 rsvd9:3;
u32 exit_zero_cnt:6;
-   u32 rsvd8:2;
+   u32 rsvd10:2;
 
-   u32 hl_switch_cnt;
-   u32 lp_byte_clk;
u32 clk_lane_switch_cnt;
+   u32 hl_switch_cnt;
+
+   u32 rsvd11[6];
+
+   /* timings based on dphy spec */
+   u8 tclk_miss;
+   u8 tclk_post;
+   u8 rsvd12;
+   u8 tclk_pre;
+   u8 tclk_prepare;
+   u8 tclk_settle;
+   u8 tclk_term_enable;
+   u8 tclk_trail;
+   u16 tclk_prepare_clkzero;
+   u8 rsvd13;
+   u8 td_term_enable;
+   u8 teot;
+   u8 ths_exit;
+   u8 ths_prepare;
+   u16 ths_prepare_hszero;
+   u8 rsvd14;
+   u8 ths_settle;
+   u8

[Intel-gfx] [PATCH 0/2] Support for new MIPI Blocks in VBT

2014-02-12 Thread Shobhit Kumar
Hi,
To support a plethora of MIPI panels, the VBT has been enhanced to support
multiple panels in a generic manner. This involves adding one MIPI configuration
block (#52) which provide all panel specific configuration data along with the 
dphy configuration information as per panel/tcon specs. Also a sequence (#53) 
block 
is added to provide required sequences for panel enabling.

The driver will use this parsed data to enable the panel which is described in 
these
two block. The i-g-t tool intel_parse_bios changes to parse these new block is 
WIP.

The generic driver will be as one of sub-encoder driver in the existing design 
to support 
MIPI. Followup patches for this driver will come next.

Regards
Shobhit

Shobhit Kumar (2):
  drm/i915: Update VBT data structures to have MIPI block enhancements
  drm/i915: Add parsing support for new MIPI blocks in VBT

 drivers/gpu/drm/i915/i915_drv.h   |   6 ++
 drivers/gpu/drm/i915/intel_bios.c | 178 ++--
 drivers/gpu/drm/i915/intel_bios.h | 186 --
 drivers/gpu/drm/i915/intel_dsi.h  |   3 +
 4 files changed, 340 insertions(+), 33 deletions(-)

-- 
1.8.3.2

___
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/intel-gfx


[Intel-gfx] [PATCH 2/2] drm/i915: Add parsing support for new MIPI blocks in VBT

2014-02-12 Thread Shobhit Kumar
The parser extracts the config block(#52) and sequence(#53) data
and store in private data structures.

Signed-off-by: Shobhit Kumar 
---
 drivers/gpu/drm/i915/i915_drv.h   |   6 ++
 drivers/gpu/drm/i915/intel_bios.c | 175 --
 drivers/gpu/drm/i915/intel_bios.h |  34 
 drivers/gpu/drm/i915/intel_dsi.h  |   1 +
 4 files changed, 211 insertions(+), 5 deletions(-)

diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h
index 728b9c3..9bede78 100644
--- a/drivers/gpu/drm/i915/i915_drv.h
+++ b/drivers/gpu/drm/i915/i915_drv.h
@@ -1250,7 +1250,13 @@ struct intel_vbt_data {
 
/* MIPI DSI */
struct {
+   u8 seq_version;
u16 panel_id;
+   struct mipi_config *config;
+   struct mipi_pps_data *pps;
+   u32 size;
+   u8 *data;
+   u8 *sequence[MIPI_SEQ_MAX];
} dsi;
 
int crt_ddc_pin;
diff --git a/drivers/gpu/drm/i915/intel_bios.c 
b/drivers/gpu/drm/i915/intel_bios.c
index cf0b25d..9d6d063 100644
--- a/drivers/gpu/drm/i915/intel_bios.c
+++ b/drivers/gpu/drm/i915/intel_bios.c
@@ -595,19 +595,184 @@ parse_edp(struct drm_i915_private *dev_priv, struct 
bdb_header *bdb)
}
 }
 
+u8 *goto_next_sequence(u8 *data)
+{
+   u16 len;
+   /* goto first element */
+   data++;
+   while (1) {
+   switch (*data++) {
+   case MIPI_SEQ_ELEM_SEND_PKT:
+   /* skip by this element payload size
+* skip command flag and data type */
+   data += 2;
+   len = *((u16 *)data);
+   /* skip by len */
+   data = data + 2 + len;
+   break;
+   case MIPI_SEQ_ELEM_DELAY:
+   data += 4;
+   break;
+   case MIPI_SEQ_ELEM_GPIO:
+   data += 2;
+   break;
+   default:
+   DRM_ERROR("Unknown element\n");
+   break;
+   }
+
+   /* end of sequence ? */
+   if (*data == 0)
+   break;
+   }
+   /* goto next sequence or end of block byte */
+   data++;
+   return data;
+}
+
 static void
 parse_mipi(struct drm_i915_private *dev_priv, struct bdb_header *bdb)
 {
-   struct bdb_mipi *mipi;
+   struct bdb_mipi_config *start;
+   struct bdb_mipi_sequence *sequence;
+   struct mipi_config *config;
+   struct mipi_pps_data *pps;
+   char *data, *seq_data, *seq_start;
+   int i, panel_id, seq_size;
+
+   /* Initialize this to undefined indicating no generic MIPI support */
+   dev_priv->vbt.dsi.panel_id = MIPI_DSI_UNDEFINED_PANEL_ID;
+
+   /* Block #40 is already parsed and panel_fixed_mode is
+* stored in dev_priv->lfp_lvds_vbt_mode
+* resuse this when needed
+*/
 
-   mipi = find_section(bdb, BDB_MIPI_CONFIG);
-   if (!mipi) {
-   DRM_DEBUG_KMS("No MIPI BDB found");
+   /* Parse #52 for panel index used from panel_type already
+* parsed
+*/
+   start = find_section(bdb, BDB_MIPI_CONFIG);
+   if (!start) {
+   DRM_DEBUG_KMS("No MIPI config BDB found");
return;
}
 
-   /* XXX: add more info */
+   DRM_DEBUG_DRIVER("Found MIPI Config block, panel index = %d\n",
+   panel_type);
+
+   /*
+* get hold of the correct configuration block and pps data as per
+* the panel_type as index
+*/
+   config = &start->config[panel_type];
+   pps = (struct mipi_pps_data *) &start->config[MAX_MIPI_CONFIGURATIONS];
+   pps = &pps[panel_type];
+
+   /* store as of now full data. Trim when we realise all is not needed */
+   dev_priv->vbt.dsi.config =
+   kzalloc(sizeof(struct mipi_config), GFP_KERNEL);
+   if (!dev_priv->vbt.dsi.config)
+   return;
+
+   dev_priv->vbt.dsi.pps =
+   kzalloc(sizeof(struct mipi_pps_data), GFP_KERNEL);
+   if (!dev_priv->vbt.dsi.pps) {
+   kfree(dev_priv->vbt.dsi.config);
+   return;
+   }
+
+   memcpy(dev_priv->vbt.dsi.config, config, sizeof(*config));
+   memcpy(dev_priv->vbt.dsi.pps, pps, sizeof(*pps));
+
+   /* We have mandatory mipi config blocks. Initialize as generic panel */
dev_priv->vbt.dsi.panel_id = MIPI_DSI_GENERIC_PANEL_ID;
+
+   /* Check if we have sequence block as well */
+   sequence = find_section(bdb, BDB_MIPI_SEQUENCE);
+   if (!sequence) {
+   DRM_DEBUG_KMS("No MIPI Sequnece BDB found");
+   DRM_DEBUG_DRIVER("MIPI related vbt parsing 

Re: [Intel-gfx] [PATCH 1/2] drm/i915: Update VBT data structures to have MIPI block enhancements

2014-02-13 Thread Shobhit Kumar

Hi

On Thursday 13 February 2014 12:47 PM, Jani Nikula wrote:

On Thu, 13 Feb 2014, Shobhit Kumar  wrote:

MIPI Block #52 which provides configuration details for the MIPI panel
including dphy settings as per panel and tcon specs

Block #53 gives information on panel enable sequences

Signed-off-by: Shobhit Kumar 
---
  drivers/gpu/drm/i915/intel_bios.c |   5 +-
  drivers/gpu/drm/i915/intel_bios.h | 152 +++---
  drivers/gpu/drm/i915/intel_dsi.h  |   2 +
  3 files changed, 130 insertions(+), 29 deletions(-)

diff --git a/drivers/gpu/drm/i915/intel_bios.c 
b/drivers/gpu/drm/i915/intel_bios.c
index 86b95ca..cf0b25d 100644
--- a/drivers/gpu/drm/i915/intel_bios.c
+++ b/drivers/gpu/drm/i915/intel_bios.c
@@ -30,6 +30,7 @@
  #include 
  #include "i915_drv.h"
  #include "intel_bios.h"
+#include "intel_dsi.h"


Hmm, I think I'd like it better if the interface from bios to elsewhere
was defined in intel_bios.h, i.e. move the required #defines from
intel_dsi.h to intel_bios.h.



Ok. Yeah looks a little awkward. Will move



  #define   SLAVE_ADDR1 0x70
  #define   SLAVE_ADDR2 0x72
@@ -599,14 +600,14 @@ parse_mipi(struct drm_i915_private *dev_priv, struct 
bdb_header *bdb)
  {
struct bdb_mipi *mipi;

-   mipi = find_section(bdb, BDB_MIPI);
+   mipi = find_section(bdb, BDB_MIPI_CONFIG);
if (!mipi) {
DRM_DEBUG_KMS("No MIPI BDB found");
return;
}

/* XXX: add more info */
-   dev_priv->vbt.dsi.panel_id = mipi->panel_id;
+   dev_priv->vbt.dsi.panel_id = MIPI_DSI_GENERIC_PANEL_ID;
  }

  static void parse_ddi_port(struct drm_i915_private *dev_priv, enum port port,
diff --git a/drivers/gpu/drm/i915/intel_bios.h 
b/drivers/gpu/drm/i915/intel_bios.h
index 282de5e..8345e0e 100644
--- a/drivers/gpu/drm/i915/intel_bios.h
+++ b/drivers/gpu/drm/i915/intel_bios.h
@@ -104,7 +104,8 @@ struct vbios_data {
  #define BDB_LVDS_LFP_DATA  42
  #define BDB_LVDS_BACKLIGHT 43
  #define BDB_LVDS_POWER 44
-#define BDB_MIPI50
+#define BDB_MIPI_CONFIG 52
+#define BDB_MIPI_SEQUENCE   53
  #define BDB_SKIP  254 /* VBIOS private block, ignore */

  struct bdb_general_features {
@@ -711,44 +712,141 @@ int intel_parse_bios(struct drm_device *dev);
  #define DVO_PORT_DPD  9
  #define DVO_PORT_DPA  10

-/* MIPI DSI panel info */
-struct bdb_mipi {
+/* Block 52 contains MIPI Panel info
+ * 6 such enteries will there. Index into correct
+ * entery is based on the panel_index in #40 LFP
+ */
+#define MAX_MIPI_CONFIGURATIONS6
+struct mipi_config {
u16 panel_id;
-   u16 bridge_revision;

-   /* General params */
+   /* General Params */
u32 dithering:1;
-   u32 bpp_pixel_format:1;
u32 rsvd1:1;
-   u32 dphy_valid:1;
-   u32 resvd2:28;
-
-   u16 port_info;
-   u16 rsvd3:2;
-   u16 num_lanes:2;
-   u16 rsvd4:12;
-
-   /* DSI config */
-   u16 virt_ch_num:2;
-   u16 vtm:2;
-   u16 rsvd5:12;
+   u32 panel_type:1;
+   u32 panel_arch_type:2;
+   u32 cmd_mode:1;
+   u32 vtm:2;
+   u32 cabc:1;
+   u32 pwm_blc:1;
+
+   /* Bit 13:10
+* 000 - Reserved, 001 - RGB565, 002 - RGB666,
+* 011 - RGB666Loosely packed, 100 - RGB888,
+* others - rsvd
+*/
+   u32 videomode_color_format:4;

-   u32 dsi_clock;
+   /* Bit 15:14
+* 0 - No rotation, 1 - 90 degree
+* 2 - 180 degree, 3 - 270 degree
+*/
+   u32 rotation:2;
+   u32 bta:1;
+   u32 rsvd2:15;
+
+   /* 2 byte Port Description */
+   u16 dual_link:2;
+   u16 lane_cnt:2;
+   u16 rsvd3:12;
+
+   /* 2 byte DSI COntroller params */
+   /* 0 - Using DSI PHY, 1 - TE usage */
+   u16 dsi_usage:1;
+   u16 rsvd4:15;
+
+   u8 rsvd5[5];
+   u32 dsi_ddr_clk;
u32 bridge_ref_clk;
-   u16 rsvd_pwr;

-   /* Dphy Params */
-   u32 prepare_cnt:5;
-   u32 rsvd6:3;
+   u8 byte_clk_sel:2;
+   u8 rsvd6:6;


Per the spec you sent me, there's one more reserved byte here.


+
+   /* DPHY Flags */
+   u16 dphy_param_valid:1;
+   u16 eot_disabled:1;
+   u16 clk_stop:1;
+   u16 rsvd7:13;
+
+   u32 hs_tx_timeout;
+   u32 lp_rx_timeout;
+   u32 turn_around_timeout;
+   u32 device_reset_timer;
+   u32 master_init_timer;
+   u32 dbi_bw_timer;
+   u32 lp_byte_clk_val;
+
+   /*  4 byte Dphy Params */
+   u32 prepare_cnt:6;
+   u32 rsvd8:2;


Per the spec you sent me, prepare_cnt is 5 bits, reserved 3 bits.


u32 clk_zero_cnt:8;
u32 trail_cnt:5;
-   u32 rsvd7:3;
+   u32 rsvd9:3;
u32 exit_zero_cnt:6;
-   u32 rsvd8:2;
+   u32 rsvd10:2;


For this reserved field the spec is clearly bogus...



-   u32 hl_switch_cnt;
-   u32 lp_byte_clk;

[Intel-gfx] [v2 2/2] drm/i915: Add parsing support for new MIPI blocks in VBT

2014-02-20 Thread Shobhit Kumar
The parser extracts the config block(#52) and sequence(#53) data
and store in private data structures.

v2: Address review comments by Jani
- adjust code for the structure changes for bdb_mipi_config
- add boundry and buffer overflow checks as suggested
- use kmemdup instead of kmalloc and memcpy

Signed-off-by: Shobhit Kumar 
---
 drivers/gpu/drm/i915/i915_drv.h   |   6 ++
 drivers/gpu/drm/i915/intel_bios.c | 162 --
 drivers/gpu/drm/i915/intel_bios.h |  34 
 3 files changed, 197 insertions(+), 5 deletions(-)

diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h
index 728b9c3..5056ced 100644
--- a/drivers/gpu/drm/i915/i915_drv.h
+++ b/drivers/gpu/drm/i915/i915_drv.h
@@ -1251,6 +1251,12 @@ struct intel_vbt_data {
/* MIPI DSI */
struct {
u16 panel_id;
+   struct mipi_config *config;
+   struct mipi_pps_data *pps;
+   u8 seq_version;
+   u32 size;
+   u8 *data;
+   u8 *sequence[MIPI_SEQ_MAX];
} dsi;
 
int crt_ddc_pin;
diff --git a/drivers/gpu/drm/i915/intel_bios.c 
b/drivers/gpu/drm/i915/intel_bios.c
index 4867f4c..ac37f6f 100644
--- a/drivers/gpu/drm/i915/intel_bios.c
+++ b/drivers/gpu/drm/i915/intel_bios.c
@@ -594,19 +594,171 @@ parse_edp(struct drm_i915_private *dev_priv, struct 
bdb_header *bdb)
}
 }
 
+static u8 *goto_next_sequence(u8 *data, int *size)
+{
+   u16 len;
+   int tmp = *size;
+   /* goto first element */
+   data++;
+   while (1) {
+   switch (*data++) {
+   case MIPI_SEQ_ELEM_SEND_PKT:
+   /* skip by this element payload size
+* skip command flag and data type */
+   data += 2;
+   len = *((u16 *)data);
+   /* skip by len */
+   data = data + 2 + len;
+   tmp = tmp - 2 - len;
+   break;
+   case MIPI_SEQ_ELEM_DELAY:
+   data += 4;
+   tmp = tmp - 4;
+   break;
+   case MIPI_SEQ_ELEM_GPIO:
+   data += 2;
+   tmp = tmp - 2;
+   break;
+   default:
+   DRM_ERROR("Unknown element\n");
+   break;
+   }
+
+   if (tmp < 0)
+   WARN(1, "Reading beyond remaining sequence size\n");
+
+   /* end of sequence ? */
+   if (*data == 0)
+   break;
+   }
+
+   /* goto next sequence or end of block byte */
+   data++;
+   tmp--;
+
+   /* update amount of data left for the sequence block to be parsed */
+   *size = tmp;
+   return data;
+}
+
 static void
 parse_mipi(struct drm_i915_private *dev_priv, struct bdb_header *bdb)
 {
-   struct bdb_mipi *mipi;
+   struct bdb_mipi_config *start;
+   struct bdb_mipi_sequence *sequence;
+   struct mipi_config *config;
+   struct mipi_pps_data *pps;
+   u8 *data, *seq_data;
+   int i, panel_id, seq_size;
+   u16 block_size;
+
+   /* Initialize this to undefined indicating no generic MIPI support */
+   dev_priv->vbt.dsi.panel_id = MIPI_DSI_UNDEFINED_PANEL_ID;
+
+   /* Block #40 is already parsed and panel_fixed_mode is
+* stored in dev_priv->lfp_lvds_vbt_mode
+* resuse this when needed
+*/
 
-   mipi = find_section(bdb, BDB_MIPI_CONFIG);
-   if (!mipi) {
-   DRM_DEBUG_KMS("No MIPI BDB found");
+   /* Parse #52 for panel index used from panel_type already
+* parsed
+*/
+   start = find_section(bdb, BDB_MIPI_CONFIG);
+   if (!start) {
+   DRM_DEBUG_KMS("No MIPI config BDB found");
return;
}
 
-   /* XXX: add more info */
+   DRM_DEBUG_DRIVER("Found MIPI Config block, panel index = %d\n",
+   panel_type);
+
+   /*
+* get hold of the correct configuration block and pps data as per
+* the panel_type as index
+*/
+   config = &start->config[panel_type];
+   pps = &start->pps[panel_type];
+
+   /* store as of now full data. Trim when we realise all is not needed */
+   dev_priv->vbt.dsi.config = kmemdup(config, sizeof(struct mipi_config), 
GFP_KERNEL);
+   if (!dev_priv->vbt.dsi.config)
+   return;
+
+   dev_priv->vbt.dsi.pps = kmemdup(pps, sizeof(struct mipi_pps_data), 
GFP_KERNEL);
+   if (!dev_priv->vbt.dsi.pps) {
+   kfree(dev_priv->vbt.dsi.config);
+   return;
+   }
+
+   /* We have mandatory mipi config blocks. Initialize as generic panel */
 

[Intel-gfx] [v2 1/2] drm/i915: Update VBT data structures to have MIPI block enhancements

2014-02-20 Thread Shobhit Kumar
MIPI Block #52 which provides configuration details for the MIPI panel
including dphy settings as per panel and tcon specs

Block #53 gives information on panel enable sequences

v2: Address review comemnts from Jani
- Move panel ids from intel_dsi.h to intel_bios.h
- bdb_mipi_config structure improvements for cleaner code
- Adding units for the pps delays, all in ms
- change data structure to be more cleaner and simple

Signed-off-by: Shobhit Kumar 
---
 drivers/gpu/drm/i915/intel_bios.c |   4 +-
 drivers/gpu/drm/i915/intel_bios.h | 174 +++---
 2 files changed, 147 insertions(+), 31 deletions(-)

diff --git a/drivers/gpu/drm/i915/intel_bios.c 
b/drivers/gpu/drm/i915/intel_bios.c
index 86b95ca..4867f4c 100644
--- a/drivers/gpu/drm/i915/intel_bios.c
+++ b/drivers/gpu/drm/i915/intel_bios.c
@@ -599,14 +599,14 @@ parse_mipi(struct drm_i915_private *dev_priv, struct 
bdb_header *bdb)
 {
struct bdb_mipi *mipi;
 
-   mipi = find_section(bdb, BDB_MIPI);
+   mipi = find_section(bdb, BDB_MIPI_CONFIG);
if (!mipi) {
DRM_DEBUG_KMS("No MIPI BDB found");
return;
}
 
/* XXX: add more info */
-   dev_priv->vbt.dsi.panel_id = mipi->panel_id;
+   dev_priv->vbt.dsi.panel_id = MIPI_DSI_GENERIC_PANEL_ID;
 }
 
 static void parse_ddi_port(struct drm_i915_private *dev_priv, enum port port,
diff --git a/drivers/gpu/drm/i915/intel_bios.h 
b/drivers/gpu/drm/i915/intel_bios.h
index 282de5e..162d0d2 100644
--- a/drivers/gpu/drm/i915/intel_bios.h
+++ b/drivers/gpu/drm/i915/intel_bios.h
@@ -104,7 +104,8 @@ struct vbios_data {
 #define BDB_LVDS_LFP_DATA   42
 #define BDB_LVDS_BACKLIGHT  43
 #define BDB_LVDS_POWER  44
-#define BDB_MIPI50
+#define BDB_MIPI_CONFIG 52
+#define BDB_MIPI_SEQUENCE   53
 #define BDB_SKIP   254 /* VBIOS private block, ignore */
 
 struct bdb_general_features {
@@ -711,44 +712,159 @@ int intel_parse_bios(struct drm_device *dev);
 #define DVO_PORT_DPD   9
 #define DVO_PORT_DPA   10
 
-/* MIPI DSI panel info */
-struct bdb_mipi {
-   u16 panel_id;
-   u16 bridge_revision;
-
-   /* General params */
-   u32 dithering:1;
-   u32 bpp_pixel_format:1;
-   u32 rsvd1:1;
-   u32 dphy_valid:1;
-   u32 resvd2:28;
+/* Block 52 contains MIPI Panel info
+ * 6 such enteries will there. Index into correct
+ * entery is based on the panel_index in #40 LFP
+ */
+#define MAX_MIPI_CONFIGURATIONS6
 
-   u16 port_info;
-   u16 rsvd3:2;
-   u16 num_lanes:2;
-   u16 rsvd4:12;
+#define MIPI_DSI_UNDEFINED_PANEL_ID0
+#define MIPI_DSI_GENERIC_PANEL_ID  1
 
-   /* DSI config */
-   u16 virt_ch_num:2;
-   u16 vtm:2;
-   u16 rsvd5:12;
+struct mipi_config {
+   u16 panel_id;
 
-   u32 dsi_clock;
+   /* General Params */
+   u32 enable_dithering:1;
+   u32 rsvd1:1;
+   u32 is_bridge:1;
+
+   u32 panel_arch_type:2;
+   u32 is_cmd_mode:1;
+
+#define NON_BURST_SYNC_PULSE   0x1
+#define NON_BURST_SYNC_EVENTS  0x2
+#define BURST_MODE 0x3
+   u32 video_transfer_mode:2;
+
+   u32 cabc_supported:1;
+   u32 pwm_blc:1;
+
+   /* Bit 13:10 */
+#define PIXEL_FORMAT_RGB5650x1
+#define PIXEL_FORMAT_RGB6660x2
+#define PIXEL_FORMAT_RGB666_LOOSELY_PACKED 0x3
+#define PIXEL_FORMAT_RGB8880x4
+   u32 videomode_color_format:4;
+
+   /* Bit 15:14 */
+#define ENABLE_ROTATION_0  0x0
+#define ENABLE_ROTATION_90 0x1
+#define ENABLE_ROTATION_1800x2
+#define ENABLE_ROTATION_2700x3
+   u32 rotation:2;
+   u32 bta_enabled:1;
+   u32 rsvd2:15;
+
+   /* 2 byte Port Description */
+#define DUAL_LINK_NOT_SUPPORTED0
+#define DUAL_LINK_FRONT_BACK   1
+#define DUAL_LINK_PIXEL_ALT2
+   u16 dual_link:2;
+   u16 lane_cnt:2;
+   u16 rsvd3:12;
+
+   u16 rsvd4;
+
+   u8 rsvd5[5];
+   u32 dsi_ddr_clk;
u32 bridge_ref_clk;
-   u16 rsvd_pwr;
 
-   /* Dphy Params */
-   u32 prepare_cnt:5;
-   u32 rsvd6:3;
+#define  BYTE_CLK_SEL_20MHZ0
+#define  BYTE_CLK_SEL_10MHZ1
+#define  BYTE_CLK_SEL_5MHZ 2
+   u8 byte_clk_sel:2;
+
+   u8 rsvd6:6;
+
+   /* DPHY Flags */
+   u16 dphy_param_valid:1;
+   u16 eot_pkt_disabled:1;
+   u16 enable_clk_stop:1;
+   u16 rsvd7:13;
+
+   u32 hs_tx_timeout;
+   u32 lp_rx_timeout;
+   u32 turn_around_timeout;
+   u32 device_reset_timer;
+   u32 master_init_timer;
+   u32 dbi_bw_timer;
+   u32 lp_byte_clk_val;
+
+   /*  4 byte Dphy Params */
+   u32 prepare_cnt:6;
+   u32 rsvd8:2;
u32 clk_zero_cnt:8;
u32 trail_cnt:5;
-   u32 rsvd7:3;
+   u32 rsvd9:3;
u32 exit_zero_cnt:6;
-   u32 rsvd8:2;
+   u32 rsvd10:2;
 
-   u32 hl_swit

[Intel-gfx] [v2 0/2] Support for new MIPI Blocks in VBT

2014-02-20 Thread Shobhit Kumar
Hi,
To support a plethora of MIPI panels, the VBT has been enhanced to support
multiple panels in a generic manner. This involves adding one MIPI configuration
block (#52) which provide all panel specific configuration data along with the 
dphy configuration information as per panel/tcon specs. Also a sequence (#53) 
block 
is added to provide required sequences for panel enabling.

The driver will use this parsed data to enable the panel which is described in 
these
two block. The i-g-t tool intel_parse_bios changes to parse these new block is 
WIP.

The generic driver will be as one of sub-encoder driver in the existing design 
to support 
MIPI. Followup patches for this driver will come next.

v2: Address review comments from Jani Nikula
- update datastructures and related code  to enable cleaner and simpler code
- using kmemdup instead of kmalloc and memcpy
- Proper error detection during parsing MIPI sequence block

Regards
Shobhit

Shobhit Kumar (2):
  drm/i915: Update VBT data structures to have MIPI block enhancements
  drm/i915: Add parsing support for new MIPI blocks in VBT

 drivers/gpu/drm/i915/i915_drv.h   |   6 ++
 drivers/gpu/drm/i915/intel_bios.c | 164 --
 drivers/gpu/drm/i915/intel_bios.h | 208 --
 3 files changed, 343 insertions(+), 35 deletions(-)

-- 
1.8.3.2

___
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/intel-gfx


Re: [Intel-gfx] [v2 1/2] drm/i915: Update VBT data structures to have MIPI block enhancements

2014-02-27 Thread Shobhit Kumar

On Thursday 27 February 2014 08:18 PM, Jani Nikula wrote:

On Thu, 20 Feb 2014, Shobhit Kumar  wrote:

+/* Block 52 contains MIPI configuration block
+ * 6 * bdb_mipi_config, followed by 6 pps data
+ * block below
+ *
+ * all delays in ms


The spec you sent me has "... delay in 100us unit" for MIPI PPS entries
which is weird and which is the reason I asked you to document the
units. Please check.


Yeah, I made a mistake. It *is* in units of 100us. Will fix this.

Regards
Shobhit
___
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/intel-gfx


[Intel-gfx] [PATCH] drm/i915: Update VBT data structures to have MIPI block enhancements

2014-02-27 Thread Shobhit Kumar
MIPI Block #52 which provides configuration details for the MIPI panel
including dphy settings as per panel and tcon specs

Block #53 gives information on panel enable sequences

v2: Address review comemnts from Jani
- Move panel ids from intel_dsi.h to intel_bios.h
- bdb_mipi_config structure improvements for cleaner code
- Adding units for the pps delays, all in ms
- change data structure to be more cleaner and simple

v3: Corrected the unit for pps delays as 100us

Signed-off-by: Shobhit Kumar 
Reviewed-by: Jani Nikula 
---
 drivers/gpu/drm/i915/intel_bios.c |   4 +-
 drivers/gpu/drm/i915/intel_bios.h | 174 +++---
 2 files changed, 147 insertions(+), 31 deletions(-)

diff --git a/drivers/gpu/drm/i915/intel_bios.c 
b/drivers/gpu/drm/i915/intel_bios.c
index 86b95ca..4867f4c 100644
--- a/drivers/gpu/drm/i915/intel_bios.c
+++ b/drivers/gpu/drm/i915/intel_bios.c
@@ -599,14 +599,14 @@ parse_mipi(struct drm_i915_private *dev_priv, struct 
bdb_header *bdb)
 {
struct bdb_mipi *mipi;
 
-   mipi = find_section(bdb, BDB_MIPI);
+   mipi = find_section(bdb, BDB_MIPI_CONFIG);
if (!mipi) {
DRM_DEBUG_KMS("No MIPI BDB found");
return;
}
 
/* XXX: add more info */
-   dev_priv->vbt.dsi.panel_id = mipi->panel_id;
+   dev_priv->vbt.dsi.panel_id = MIPI_DSI_GENERIC_PANEL_ID;
 }
 
 static void parse_ddi_port(struct drm_i915_private *dev_priv, enum port port,
diff --git a/drivers/gpu/drm/i915/intel_bios.h 
b/drivers/gpu/drm/i915/intel_bios.h
index 282de5e..83b7629 100644
--- a/drivers/gpu/drm/i915/intel_bios.h
+++ b/drivers/gpu/drm/i915/intel_bios.h
@@ -104,7 +104,8 @@ struct vbios_data {
 #define BDB_LVDS_LFP_DATA   42
 #define BDB_LVDS_BACKLIGHT  43
 #define BDB_LVDS_POWER  44
-#define BDB_MIPI50
+#define BDB_MIPI_CONFIG 52
+#define BDB_MIPI_SEQUENCE   53
 #define BDB_SKIP   254 /* VBIOS private block, ignore */
 
 struct bdb_general_features {
@@ -711,44 +712,159 @@ int intel_parse_bios(struct drm_device *dev);
 #define DVO_PORT_DPD   9
 #define DVO_PORT_DPA   10
 
-/* MIPI DSI panel info */
-struct bdb_mipi {
-   u16 panel_id;
-   u16 bridge_revision;
-
-   /* General params */
-   u32 dithering:1;
-   u32 bpp_pixel_format:1;
-   u32 rsvd1:1;
-   u32 dphy_valid:1;
-   u32 resvd2:28;
+/* Block 52 contains MIPI Panel info
+ * 6 such enteries will there. Index into correct
+ * entery is based on the panel_index in #40 LFP
+ */
+#define MAX_MIPI_CONFIGURATIONS6
 
-   u16 port_info;
-   u16 rsvd3:2;
-   u16 num_lanes:2;
-   u16 rsvd4:12;
+#define MIPI_DSI_UNDEFINED_PANEL_ID0
+#define MIPI_DSI_GENERIC_PANEL_ID  1
 
-   /* DSI config */
-   u16 virt_ch_num:2;
-   u16 vtm:2;
-   u16 rsvd5:12;
+struct mipi_config {
+   u16 panel_id;
 
-   u32 dsi_clock;
+   /* General Params */
+   u32 enable_dithering:1;
+   u32 rsvd1:1;
+   u32 is_bridge:1;
+
+   u32 panel_arch_type:2;
+   u32 is_cmd_mode:1;
+
+#define NON_BURST_SYNC_PULSE   0x1
+#define NON_BURST_SYNC_EVENTS  0x2
+#define BURST_MODE 0x3
+   u32 video_transfer_mode:2;
+
+   u32 cabc_supported:1;
+   u32 pwm_blc:1;
+
+   /* Bit 13:10 */
+#define PIXEL_FORMAT_RGB5650x1
+#define PIXEL_FORMAT_RGB6660x2
+#define PIXEL_FORMAT_RGB666_LOOSELY_PACKED 0x3
+#define PIXEL_FORMAT_RGB8880x4
+   u32 videomode_color_format:4;
+
+   /* Bit 15:14 */
+#define ENABLE_ROTATION_0  0x0
+#define ENABLE_ROTATION_90 0x1
+#define ENABLE_ROTATION_1800x2
+#define ENABLE_ROTATION_2700x3
+   u32 rotation:2;
+   u32 bta_enabled:1;
+   u32 rsvd2:15;
+
+   /* 2 byte Port Description */
+#define DUAL_LINK_NOT_SUPPORTED0
+#define DUAL_LINK_FRONT_BACK   1
+#define DUAL_LINK_PIXEL_ALT2
+   u16 dual_link:2;
+   u16 lane_cnt:2;
+   u16 rsvd3:12;
+
+   u16 rsvd4;
+
+   u8 rsvd5[5];
+   u32 dsi_ddr_clk;
u32 bridge_ref_clk;
-   u16 rsvd_pwr;
 
-   /* Dphy Params */
-   u32 prepare_cnt:5;
-   u32 rsvd6:3;
+#define  BYTE_CLK_SEL_20MHZ0
+#define  BYTE_CLK_SEL_10MHZ1
+#define  BYTE_CLK_SEL_5MHZ 2
+   u8 byte_clk_sel:2;
+
+   u8 rsvd6:6;
+
+   /* DPHY Flags */
+   u16 dphy_param_valid:1;
+   u16 eot_pkt_disabled:1;
+   u16 enable_clk_stop:1;
+   u16 rsvd7:13;
+
+   u32 hs_tx_timeout;
+   u32 lp_rx_timeout;
+   u32 turn_around_timeout;
+   u32 device_reset_timer;
+   u32 master_init_timer;
+   u32 dbi_bw_timer;
+   u32 lp_byte_clk_val;
+
+   /*  4 byte Dphy Params */
+   u32 prepare_cnt:6;
+   u32 rsvd8:2;
u32 clk_zero_cnt:8;
u32 trail_cnt:5;
-   u32 rsvd7:3;
+   u32 rsvd9:3;
u32 exit_zero

[Intel-gfx] [PATCH 1/7] drm/i915: Program Rcomp and band gap reset everytime we resume from power gate

2014-04-09 Thread Shobhit Kumar
Signed-off-by: Shobhit Kumar 
Reviewed-by: Jani Nikula 
---
 drivers/gpu/drm/i915/intel_dsi.c | 12 +---
 1 file changed, 9 insertions(+), 3 deletions(-)

diff --git a/drivers/gpu/drm/i915/intel_dsi.c b/drivers/gpu/drm/i915/intel_dsi.c
index 3365664..7ceb8c6 100644
--- a/drivers/gpu/drm/i915/intel_dsi.c
+++ b/drivers/gpu/drm/i915/intel_dsi.c
@@ -110,6 +110,15 @@ static void intel_dsi_device_ready(struct intel_encoder 
*encoder)
 
DRM_DEBUG_KMS("\n");
 
+   mutex_lock(&dev_priv->dpio_lock);
+   /* program rcomp for compliance, reduce from 50 ohms to 45 ohms
+* needed everytime after power gate */
+   vlv_flisdsi_write(dev_priv, 0x04, 0x0004);
+   mutex_unlock(&dev_priv->dpio_lock);
+
+   /* bandgap reset is needed after everytime we do power gate */
+   band_gap_reset(dev_priv);
+
val = I915_READ(MIPI_PORT_CTRL(pipe));
I915_WRITE(MIPI_PORT_CTRL(pipe), val | LP_OUTPUT_HOLD);
usleep_range(1000, 1500);
@@ -379,9 +388,6 @@ static void intel_dsi_mode_set(struct intel_encoder 
*intel_encoder)
 
DRM_DEBUG_KMS("pipe %c\n", pipe_name(pipe));
 
-   /* XXX: Location of the call */
-   band_gap_reset(dev_priv);
-
/* escape clock divider, 20MHz, shared for A and C. device ready must be
 * off when doing this! txclkesc? */
tmp = I915_READ(MIPI_CTRL(0));
-- 
1.8.3.2

___
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/intel-gfx


[Intel-gfx] [PATCH 7/7] drm/i915: Enable RANDOM resolution support for MIPI panels

2014-04-09 Thread Shobhit Kumar
Some MIPI panels might not have resolution which is a multiple of 64 like
1366x768. Enable this feature for such panels by default

Signed-off-by: Shobhit Kumar 
Reviewed-by: Jani Nikula 
---
 drivers/gpu/drm/i915/intel_dsi.c | 7 ++-
 1 file changed, 6 insertions(+), 1 deletion(-)

diff --git a/drivers/gpu/drm/i915/intel_dsi.c b/drivers/gpu/drm/i915/intel_dsi.c
index b5948b7..4e271c7 100644
--- a/drivers/gpu/drm/i915/intel_dsi.c
+++ b/drivers/gpu/drm/i915/intel_dsi.c
@@ -552,9 +552,14 @@ static void intel_dsi_mode_set(struct intel_encoder 
*intel_encoder)
   intel_dsi->clk_hs_to_lp_count << HS_LP_PWR_SW_CNT_SHIFT);
 
if (is_vid_mode(intel_dsi))
+   /* Some panels might have resolution which is not a multiple of
+* 64 like 1366 x 768. Enable RANDOM resolution support for such
+* panels by default */
I915_WRITE(MIPI_VIDEO_MODE_FORMAT(pipe),
intel_dsi->video_frmt_cfg_bits |
-   intel_dsi->video_mode_format);
+   intel_dsi->video_mode_format |
+   IP_TG_CONFIG |
+   RANDOM_DPI_DISPLAY_RESOLUTION);
 }
 
 static enum drm_connector_status
-- 
1.8.3.2

___
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/intel-gfx


[Intel-gfx] [PATCH 5/7] drm/i915: Panel commands can be sent only when clock is in LP11

2014-04-09 Thread Shobhit Kumar
Signed-off-by: Shobhit Kumar 
Reviewed-by: Jani Nikula 
---
 drivers/gpu/drm/i915/intel_dsi.c | 17 +
 1 file changed, 17 insertions(+)

diff --git a/drivers/gpu/drm/i915/intel_dsi.c b/drivers/gpu/drm/i915/intel_dsi.c
index dfcdb10..d8eccda 100644
--- a/drivers/gpu/drm/i915/intel_dsi.c
+++ b/drivers/gpu/drm/i915/intel_dsi.c
@@ -229,6 +229,23 @@ static void intel_dsi_disable(struct intel_encoder 
*encoder)
msleep(2);
}
 
+   /* Panel commands can be sent when clock is in LP11 */
+   I915_WRITE(MIPI_DEVICE_READY(pipe), 0x0);
+
+   temp = I915_READ(MIPI_CTRL(pipe));
+   temp &= ~ESCAPE_CLOCK_DIVIDER_MASK;
+   I915_WRITE(MIPI_CTRL(pipe), temp |
+   intel_dsi->escape_clk_div <<
+   ESCAPE_CLOCK_DIVIDER_SHIFT);
+
+   I915_WRITE(MIPI_EOT_DISABLE(pipe), CLOCKSTOP);
+
+   temp = I915_READ(MIPI_DSI_FUNC_PRG(pipe));
+   temp &= ~VID_MODE_FORMAT_MASK;
+   I915_WRITE(MIPI_DSI_FUNC_PRG(pipe), temp);
+
+   I915_WRITE(MIPI_DEVICE_READY(pipe), 0x1);
+
/* if disable packets are sent before sending shutdown packet then in
 * some next enable sequence send turn on packet error is observed */
if (intel_dsi->dev.dev_ops->disable)
-- 
1.8.3.2

___
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/intel-gfx


[Intel-gfx] [PATCH 0/7] Updated MIPI sequence for BYT

2014-04-09 Thread Shobhit Kumar
Hi,
The changes in DSI sequence are as suggested by HW and SV teams. Notable
difference apart form few WAs is that for MIPI it is suggetsed that the
PORT is enabled before PIPE and PLANE. The patch makes these changes.
So few sequence changes, few workarounds and few new feature support like
Clockstop.

A generic panel driver to enable MIPI is planned in next patchset

Known issue - 
Today the upstream kernel does not have PMIC driver amd these patches works if 
UEFI BIOS enables MIPI and reuse  BKL_EN, PANEL_EN from there, but during
suspend/resume things will still fail.

Regards
Shobhit

Shobhit Kumar (7):
  drm/i915: Program Rcomp and band gap reset everytime we resume from power gate
  drm/i915: Enable MIPI port before the plane and pipe enable
  drm/i915: Disable DPOunit clock gating
  drm/i915: Parameterize the Clockstop and escape_clk_div
  drm/i915: Panel commands can be sent only when clock is in LP11
  drm/i915: Send DPI command explicitely in LP mode
  drm/i915: Enable RANDOM resolution support for MIPI panels

 drivers/gpu/drm/i915/intel_dsi.c | 125 +++
 drivers/gpu/drm/i915/intel_dsi.h |   4 +-
 drivers/gpu/drm/i915/intel_dsi_cmd.c |   4 +-
 drivers/gpu/drm/i915/intel_dsi_cmd.h |   5 +-
 4 files changed, 108 insertions(+), 30 deletions(-)

-- 
1.8.3.2

___
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/intel-gfx


[Intel-gfx] [PATCH 4/7] drm/i915: Parameterize the Clockstop and escape_clk_div

2014-04-09 Thread Shobhit Kumar
In preparation for Generic driver

Signed-off-by: Shobhit Kumar 
Reviewed-by: Jani Nikula 
---
 drivers/gpu/drm/i915/intel_dsi.c | 11 +--
 drivers/gpu/drm/i915/intel_dsi.h |  4 +++-
 2 files changed, 12 insertions(+), 3 deletions(-)

diff --git a/drivers/gpu/drm/i915/intel_dsi.c b/drivers/gpu/drm/i915/intel_dsi.c
index 4793a5b..dfcdb10 100644
--- a/drivers/gpu/drm/i915/intel_dsi.c
+++ b/drivers/gpu/drm/i915/intel_dsi.c
@@ -495,10 +495,17 @@ static void intel_dsi_mode_set(struct intel_encoder 
*intel_encoder)
/* dphy stuff */
 
/* in terms of low power clock */
-   I915_WRITE(MIPI_INIT_COUNT(pipe), txclkesc(ESCAPE_CLOCK_DIVIDER_1, 
100));
+   I915_WRITE(MIPI_INIT_COUNT(pipe), txclkesc(intel_dsi->escape_clk_div, 
100));
+
+   val = 0;
+   if (intel_dsi->eotp_pkt == 0)
+   val |= EOT_DISABLE;
+
+   if (intel_dsi->clock_stop)
+   val |= CLOCKSTOP;
 
/* recovery disables */
-   I915_WRITE(MIPI_EOT_DISABLE(pipe), intel_dsi->eot_disable);
+   I915_WRITE(MIPI_EOT_DISABLE(pipe), val);
 
/* in terms of txbyteclkhs. actual high to low switch +
 * MIPI_STOP_STATE_STALL * MIPI_LP_BYTECLK.
diff --git a/drivers/gpu/drm/i915/intel_dsi.h b/drivers/gpu/drm/i915/intel_dsi.h
index b4a27ce..550714c 100644
--- a/drivers/gpu/drm/i915/intel_dsi.h
+++ b/drivers/gpu/drm/i915/intel_dsi.h
@@ -95,8 +95,10 @@ struct intel_dsi {
u32 video_mode_format;
 
/* eot for MIPI_EOT_DISABLE register */
-   u32 eot_disable;
+   u8 eotp_pkt;
+   u8 clock_stop;
 
+   u8 escape_clk_div;
u32 port_bits;
u32 bw_timer;
u32 dphy_reg;
-- 
1.8.3.2

___
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/intel-gfx


[Intel-gfx] [PATCH 2/7] drm/i915: Enable MIPI port before the plane and pipe enable

2014-04-09 Thread Shobhit Kumar
As per the hw team's recommendation we need to enable the MIPI port
before enabling the plane and pipe. So call MIPI port enable in
pre_enable phase itself

Signed-off-by: Shobhit Kumar 
Reviewed-by: Jani Nikula 
---
 drivers/gpu/drm/i915/intel_dsi.c | 51 ++--
 1 file changed, 33 insertions(+), 18 deletions(-)

diff --git a/drivers/gpu/drm/i915/intel_dsi.c b/drivers/gpu/drm/i915/intel_dsi.c
index 7ceb8c6..569e6c6 100644
--- a/drivers/gpu/drm/i915/intel_dsi.c
+++ b/drivers/gpu/drm/i915/intel_dsi.c
@@ -131,21 +131,6 @@ static void intel_dsi_device_ready(struct intel_encoder 
*encoder)
I915_WRITE(MIPI_DEVICE_READY(pipe), DEVICE_READY);
usleep_range(2000, 2500);
 }
-static void intel_dsi_pre_enable(struct intel_encoder *encoder)
-{
-   struct intel_dsi *intel_dsi = enc_to_intel_dsi(&encoder->base);
-
-   DRM_DEBUG_KMS("\n");
-
-   if (intel_dsi->dev.dev_ops->panel_reset)
-   intel_dsi->dev.dev_ops->panel_reset(&intel_dsi->dev);
-
-   /* put device in ready state */
-   intel_dsi_device_ready(encoder);
-
-   if (intel_dsi->dev.dev_ops->send_otp_cmds)
-   intel_dsi->dev.dev_ops->send_otp_cmds(&intel_dsi->dev);
-}
 
 static void intel_dsi_enable(struct intel_encoder *encoder)
 {
@@ -165,15 +150,45 @@ static void intel_dsi_enable(struct intel_encoder 
*encoder)
dpi_send_cmd(intel_dsi, TURN_ON);
msleep(100);
 
+   if (intel_dsi->dev.dev_ops->enable)
+   intel_dsi->dev.dev_ops->enable(&intel_dsi->dev);
+
/* assert ip_tg_enable signal */
temp = I915_READ(MIPI_PORT_CTRL(pipe)) & 
~LANE_CONFIGURATION_MASK;
temp = temp | intel_dsi->port_bits;
I915_WRITE(MIPI_PORT_CTRL(pipe), temp | DPI_ENABLE);
POSTING_READ(MIPI_PORT_CTRL(pipe));
}
+}
+
+static void intel_dsi_pre_enable(struct intel_encoder *encoder)
+{
+   struct intel_dsi *intel_dsi = enc_to_intel_dsi(&encoder->base);
+
+   DRM_DEBUG_KMS("\n");
+
+   if (intel_dsi->dev.dev_ops->panel_reset)
+   intel_dsi->dev.dev_ops->panel_reset(&intel_dsi->dev);
+
+   /* put device in ready state */
+   intel_dsi_device_ready(encoder);
 
-   if (intel_dsi->dev.dev_ops->enable)
-   intel_dsi->dev.dev_ops->enable(&intel_dsi->dev);
+   if (intel_dsi->dev.dev_ops->send_otp_cmds)
+   intel_dsi->dev.dev_ops->send_otp_cmds(&intel_dsi->dev);
+
+   /* Enable port in pre-enable phase itself because as per hw team
+* recommendation, port should be enabled befor plane & pipe */
+   intel_dsi_enable(encoder);
+}
+
+static void intel_dsi_enable_nop(struct intel_encoder *encoder)
+{
+   DRM_DEBUG_KMS("\n");
+
+   /* for DSI port enable has to be done before pipe
+* and plane enable, so port enable is done in
+* pre_enable phase itself unlike other encoders
+*/
 }
 
 static void intel_dsi_disable(struct intel_encoder *encoder)
@@ -600,7 +615,7 @@ bool intel_dsi_init(struct drm_device *dev)
intel_encoder->compute_config = intel_dsi_compute_config;
intel_encoder->pre_pll_enable = intel_dsi_pre_pll_enable;
intel_encoder->pre_enable = intel_dsi_pre_enable;
-   intel_encoder->enable = intel_dsi_enable;
+   intel_encoder->enable = intel_dsi_enable_nop;
intel_encoder->mode_set = intel_dsi_mode_set;
intel_encoder->disable = intel_dsi_disable;
intel_encoder->post_disable = intel_dsi_post_disable;
-- 
1.8.3.2

___
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/intel-gfx


[Intel-gfx] [PATCH 3/7] drm/i915: Disable DPOunit clock gating

2014-04-09 Thread Shobhit Kumar
Otherwise, this can stall pipe. We also need DPLL REFA always
enabled

Signed-off-by: Shobhit Kumar 
Reviewed-by: Jani Nikula 
---
 drivers/gpu/drm/i915/intel_dsi.c | 26 --
 1 file changed, 24 insertions(+), 2 deletions(-)

diff --git a/drivers/gpu/drm/i915/intel_dsi.c b/drivers/gpu/drm/i915/intel_dsi.c
index 569e6c6..4793a5b 100644
--- a/drivers/gpu/drm/i915/intel_dsi.c
+++ b/drivers/gpu/drm/i915/intel_dsi.c
@@ -163,16 +163,31 @@ static void intel_dsi_enable(struct intel_encoder 
*encoder)
 
 static void intel_dsi_pre_enable(struct intel_encoder *encoder)
 {
+   struct drm_device *dev = encoder->base.dev;
+   struct drm_i915_private *dev_priv = dev->dev_private;
struct intel_dsi *intel_dsi = enc_to_intel_dsi(&encoder->base);
+   struct intel_crtc *intel_crtc = to_intel_crtc(encoder->base.crtc);
+   enum pipe pipe = intel_crtc->pipe;
+   u32 tmp;
 
DRM_DEBUG_KMS("\n");
 
-   if (intel_dsi->dev.dev_ops->panel_reset)
-   intel_dsi->dev.dev_ops->panel_reset(&intel_dsi->dev);
+   /* Disable DPOunit clock gating, can stall pipe
+* and we need DPLL REFA always enabled */
+   tmp = I915_READ(DPLL(pipe));
+   tmp |= DPLL_REFA_CLK_ENABLE_VLV;
+   I915_WRITE(DPLL(pipe), tmp);
+
+   tmp = I915_READ(DSPCLK_GATE_D);
+   tmp |= DPOUNIT_CLOCK_GATE_DISABLE;
+   I915_WRITE(DSPCLK_GATE_D, tmp);
 
/* put device in ready state */
intel_dsi_device_ready(encoder);
 
+   if (intel_dsi->dev.dev_ops->panel_reset)
+   intel_dsi->dev.dev_ops->panel_reset(&intel_dsi->dev);
+
if (intel_dsi->dev.dev_ops->send_otp_cmds)
intel_dsi->dev.dev_ops->send_otp_cmds(&intel_dsi->dev);
 
@@ -251,14 +266,21 @@ static void intel_dsi_clear_device_ready(struct 
intel_encoder *encoder)
 
vlv_disable_dsi_pll(encoder);
 }
+
 static void intel_dsi_post_disable(struct intel_encoder *encoder)
 {
+   struct drm_i915_private *dev_priv = encoder->base.dev->dev_private;
struct intel_dsi *intel_dsi = enc_to_intel_dsi(&encoder->base);
+   u32 val;
 
DRM_DEBUG_KMS("\n");
 
intel_dsi_clear_device_ready(encoder);
 
+   val = I915_READ(DSPCLK_GATE_D);
+   val &= ~DPOUNIT_CLOCK_GATE_DISABLE;
+   I915_WRITE(DSPCLK_GATE_D, val);
+
if (intel_dsi->dev.dev_ops->disable_panel_power)
intel_dsi->dev.dev_ops->disable_panel_power(&intel_dsi->dev);
 }
-- 
1.8.3.2

___
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/intel-gfx


[Intel-gfx] [PATCH 6/7] drm/i915: Send DPI command explicitely in LP mode

2014-04-09 Thread Shobhit Kumar
Though HS mode also should work.

v2: Change parameter as "bool hs" as suggested by Jani

Signed-off-by: Shobhit Kumar 
Reviewed-by: Jani Nikula 
---
 drivers/gpu/drm/i915/intel_dsi.c | 5 +++--
 drivers/gpu/drm/i915/intel_dsi_cmd.c | 4 ++--
 drivers/gpu/drm/i915/intel_dsi_cmd.h | 5 -
 3 files changed, 9 insertions(+), 5 deletions(-)

diff --git a/drivers/gpu/drm/i915/intel_dsi.c b/drivers/gpu/drm/i915/intel_dsi.c
index d8eccda..b5948b7 100644
--- a/drivers/gpu/drm/i915/intel_dsi.c
+++ b/drivers/gpu/drm/i915/intel_dsi.c
@@ -147,7 +147,7 @@ static void intel_dsi_enable(struct intel_encoder *encoder)
I915_WRITE(MIPI_MAX_RETURN_PKT_SIZE(pipe), 8 * 4);
else {
msleep(20); /* XXX */
-   dpi_send_cmd(intel_dsi, TURN_ON);
+   dpi_send_cmd(intel_dsi, TURN_ON, DPI_LP_MODE_EN);
msleep(100);
 
if (intel_dsi->dev.dev_ops->enable)
@@ -218,7 +218,8 @@ static void intel_dsi_disable(struct intel_encoder *encoder)
DRM_DEBUG_KMS("\n");
 
if (is_vid_mode(intel_dsi)) {
-   dpi_send_cmd(intel_dsi, SHUTDOWN);
+   /* Send Shutdown command to the panel in LP mode */
+   dpi_send_cmd(intel_dsi, SHUTDOWN, DPI_LP_MODE_EN);
msleep(10);
 
/* de-assert ip_tg_enable signal */
diff --git a/drivers/gpu/drm/i915/intel_dsi_cmd.c 
b/drivers/gpu/drm/i915/intel_dsi_cmd.c
index 7c40f98..3eeb21b 100644
--- a/drivers/gpu/drm/i915/intel_dsi_cmd.c
+++ b/drivers/gpu/drm/i915/intel_dsi_cmd.c
@@ -389,7 +389,7 @@ int dsi_vc_generic_read(struct intel_dsi *intel_dsi, int 
channel,
  *
  * XXX: commands with data in MIPI_DPI_DATA?
  */
-int dpi_send_cmd(struct intel_dsi *intel_dsi, u32 cmd)
+int dpi_send_cmd(struct intel_dsi *intel_dsi, u32 cmd, bool hs)
 {
struct drm_encoder *encoder = &intel_dsi->base.base;
struct drm_device *dev = encoder->dev;
@@ -399,7 +399,7 @@ int dpi_send_cmd(struct intel_dsi *intel_dsi, u32 cmd)
u32 mask;
 
/* XXX: pipe, hs */
-   if (intel_dsi->hs)
+   if (hs)
cmd &= ~DPI_LP_MODE;
else
cmd |= DPI_LP_MODE;
diff --git a/drivers/gpu/drm/i915/intel_dsi_cmd.h 
b/drivers/gpu/drm/i915/intel_dsi_cmd.h
index 54c8a23..9a18cbf 100644
--- a/drivers/gpu/drm/i915/intel_dsi_cmd.h
+++ b/drivers/gpu/drm/i915/intel_dsi_cmd.h
@@ -33,6 +33,9 @@
 #include "intel_drv.h"
 #include "intel_dsi.h"
 
+#define DPI_LP_MODE_EN false
+#define DPI_HS_MODE_EN true
+
 void dsi_hs_mode_enable(struct intel_dsi *intel_dsi, bool enable);
 
 int dsi_vc_dcs_write(struct intel_dsi *intel_dsi, int channel,
@@ -47,7 +50,7 @@ int dsi_vc_dcs_read(struct intel_dsi *intel_dsi, int channel, 
u8 dcs_cmd,
 int dsi_vc_generic_read(struct intel_dsi *intel_dsi, int channel,
u8 *reqdata, int reqlen, u8 *buf, int buflen);
 
-int dpi_send_cmd(struct intel_dsi *intel_dsi, u32 cmd);
+int dpi_send_cmd(struct intel_dsi *intel_dsi, u32 cmd, bool hs);
 
 /* XXX: questionable write helpers */
 static inline int dsi_vc_dcs_write_0(struct intel_dsi *intel_dsi,
-- 
1.8.3.2

___
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/intel-gfx


Re: [Intel-gfx] [PATCH v2 5/7] drm/i915: Reorganize the DSI enable/disable sequence

2013-11-19 Thread Shobhit Kumar

On Friday 15 November 2013 02:25 PM, Daniel Vetter wrote:

On Fri, Nov 15, 2013 at 10:27:25AM +0200, Jani Nikula wrote:

On Sat, 09 Nov 2013, Shobhit Kumar  wrote:

Basically ULPS handling during enable/disable has been moved to
pre_enable and post_disable phases. PLL and panel power disable
also has been moved to post_disable phase. The ULPS entry/exit
sequneces as suggested by HW team is as follows -

During enable time -
set DEVICE_READY --> Clear DEVICE_READY --> set DEVICE_READY

And during disable time to flush all FIFOs -
set ENTER_SLEEP --> EXIT_SLEEP --> ENTER_SLEEP

Also during disbale sequnece sub-encoder disable is moved to the end
after port is disabled.

v2: Based on comments from Ville
 - Detailed epxlaination in the commit messgae
 - Moved parameter changes out into another patch
 - Backlight enabling will be a new patch

Signed-off-by: Yogesh Mohan Marimuthu 
Signed-off-by: Shobhit Kumar 
---
  drivers/gpu/drm/i915/i915_drv.h  |   11 
  drivers/gpu/drm/i915/intel_dsi.c |  111 ++
  drivers/gpu/drm/i915/intel_dsi.h |2 +
  3 files changed, 91 insertions(+), 33 deletions(-)

diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h
index a2bbff9..55c16cb 100644
--- a/drivers/gpu/drm/i915/i915_drv.h
+++ b/drivers/gpu/drm/i915/i915_drv.h
@@ -2433,6 +2433,17 @@ int vlv_freq_opcode(int ddr_freq, int val);
  #define POSTING_READ(reg) (void)I915_READ_NOTRACE(reg)
  #define POSTING_READ16(reg)   (void)I915_READ16_NOTRACE(reg)

+#define I915_WRITE_BITS(reg, val, mask) \
+do { \
+   u32 tmp, data; \
+   tmp = I915_READ((reg)); \
+   tmp &= ~(mask); \
+   data = (val) & (mask); \
+   data = data | tmp; \
+   I915_WRITE((reg), data); \
+} while(0)


I would still prefer the explicit read, modify, and write in the code
instead of this, but it's a matter of taste I'll leave for Daniel to
call the shots on.


Yeah, this looks a bit funny. We could compute the tmp value once (where
the mask is mutliple times the same thing) and then just or in the right
bits.  That should make the I915_WRITE calls fit ont on line, too, which
helps readability.

Also we put POSTING_READs before any waits to ensure the write has
actually landed. It's mostly documentation.

And while I'm at it: We generally frown upon readbacks of register value
and prefer to just keep track of things in software well enough. The
reason for that is that register readbacks allows us too much flexibility
in adding subtile state-depencies. Which long-term makes the code a real
pain to maintain.


Ok. Will work on updating the patch accordingly and take care of other 
comments as well in next patch set update soon.


Regards
Shobhit
___
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/intel-gfx


Re: [Intel-gfx] [PATCH v2 5/7] drm/i915: Reorganize the DSI enable/disable sequence

2013-12-06 Thread Shobhit Kumar

On Wednesday 20 November 2013 07:09 AM, Shobhit Kumar wrote:

On Friday 15 November 2013 02:25 PM, Daniel Vetter wrote:

On Fri, Nov 15, 2013 at 10:27:25AM +0200, Jani Nikula wrote:

On Sat, 09 Nov 2013, Shobhit Kumar  wrote:

Basically ULPS handling during enable/disable has been moved to
pre_enable and post_disable phases. PLL and panel power disable
also has been moved to post_disable phase. The ULPS entry/exit
sequneces as suggested by HW team is as follows -

During enable time -
set DEVICE_READY --> Clear DEVICE_READY --> set DEVICE_READY

And during disable time to flush all FIFOs -
set ENTER_SLEEP --> EXIT_SLEEP --> ENTER_SLEEP

Also during disbale sequnece sub-encoder disable is moved to the end
after port is disabled.

v2: Based on comments from Ville
 - Detailed epxlaination in the commit messgae
 - Moved parameter changes out into another patch
 - Backlight enabling will be a new patch

Signed-off-by: Yogesh Mohan Marimuthu

Signed-off-by: Shobhit Kumar 
---
  drivers/gpu/drm/i915/i915_drv.h  |   11 
  drivers/gpu/drm/i915/intel_dsi.c |  111
++
  drivers/gpu/drm/i915/intel_dsi.h |2 +
  3 files changed, 91 insertions(+), 33 deletions(-)

diff --git a/drivers/gpu/drm/i915/i915_drv.h
b/drivers/gpu/drm/i915/i915_drv.h
index a2bbff9..55c16cb 100644
--- a/drivers/gpu/drm/i915/i915_drv.h
+++ b/drivers/gpu/drm/i915/i915_drv.h
@@ -2433,6 +2433,17 @@ int vlv_freq_opcode(int ddr_freq, int val);
  #define POSTING_READ(reg)(void)I915_READ_NOTRACE(reg)
  #define POSTING_READ16(reg)(void)I915_READ16_NOTRACE(reg)

+#define I915_WRITE_BITS(reg, val, mask) \
+do { \
+u32 tmp, data; \
+tmp = I915_READ((reg)); \
+tmp &= ~(mask); \
+data = (val) & (mask); \
+data = data | tmp; \
+I915_WRITE((reg), data); \
+} while(0)


I would still prefer the explicit read, modify, and write in the code
instead of this, but it's a matter of taste I'll leave for Daniel to
call the shots on.


Yeah, this looks a bit funny. We could compute the tmp value once (where
the mask is mutliple times the same thing) and then just or in the right
bits.  That should make the I915_WRITE calls fit ont on line, too, which
helps readability.

Also we put POSTING_READs before any waits to ensure the write has
actually landed. It's mostly documentation.

And while I'm at it: We generally frown upon readbacks of register value
and prefer to just keep track of things in software well enough. The
reason for that is that register readbacks allows us too much flexibility
in adding subtile state-depencies. Which long-term makes the code a real
pain to maintain.


Ok. Will work on updating the patch accordingly and take care of other
comments as well in next patch set update soon.


Sorry took me more time than I anticipated to rework on this due to 
other critical stuff. Looking at the code and doing more testing I now 
confirmed that there is no READ/Modify/WRITE needed for ULPS and hence I 
will convert I915_WRITE_BITS to normal I915_WRITE. Will be sending 
updated patches on Monday


Regards
Shobhit
___
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/intel-gfx


Re: [Intel-gfx] [PATCH v2 5/7] drm/i915: Reorganize the DSI enable/disable sequence

2013-12-06 Thread Shobhit Kumar

On Friday 15 November 2013 01:57 PM, Jani Nikula wrote:

On Sat, 09 Nov 2013, Shobhit Kumar  wrote:

Basically ULPS handling during enable/disable has been moved to
pre_enable and post_disable phases. PLL and panel power disable
also has been moved to post_disable phase. The ULPS entry/exit
sequneces as suggested by HW team is as follows -

During enable time -
set DEVICE_READY --> Clear DEVICE_READY --> set DEVICE_READY

And during disable time to flush all FIFOs -
set ENTER_SLEEP --> EXIT_SLEEP --> ENTER_SLEEP

Also during disbale sequnece sub-encoder disable is moved to the end
after port is disabled.

v2: Based on comments from Ville
 - Detailed epxlaination in the commit messgae
 - Moved parameter changes out into another patch
 - Backlight enabling will be a new patch

Signed-off-by: Yogesh Mohan Marimuthu 
Signed-off-by: Shobhit Kumar 
---
  drivers/gpu/drm/i915/i915_drv.h  |   11 
  drivers/gpu/drm/i915/intel_dsi.c |  111 ++
  drivers/gpu/drm/i915/intel_dsi.h |2 +
  3 files changed, 91 insertions(+), 33 deletions(-)

diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h
index a2bbff9..55c16cb 100644
--- a/drivers/gpu/drm/i915/i915_drv.h
+++ b/drivers/gpu/drm/i915/i915_drv.h
@@ -2433,6 +2433,17 @@ int vlv_freq_opcode(int ddr_freq, int val);
  #define POSTING_READ(reg) (void)I915_READ_NOTRACE(reg)
  #define POSTING_READ16(reg)   (void)I915_READ16_NOTRACE(reg)

+#define I915_WRITE_BITS(reg, val, mask) \
+do { \
+   u32 tmp, data; \
+   tmp = I915_READ((reg)); \
+   tmp &= ~(mask); \
+   data = (val) & (mask); \
+   data = data | tmp; \
+   I915_WRITE((reg), data); \
+} while(0)


I would still prefer the explicit read, modify, and write in the code
instead of this, but it's a matter of taste I'll leave for Daniel to
call the shots on.

One reason for my dislike is how easy it will be to accidentally get the
val and mask parameters mixed up. I would instinctively put the mask
before the value (common convention of context before the rest), which
would be wrong here. I am not saying changing the order would make me
like this.


As mentioned in another mail, this is not required and I will remove it




+
+
  /* "Broadcast RGB" property */
  #define INTEL_BROADCAST_RGB_AUTO 0
  #define INTEL_BROADCAST_RGB_FULL 1
diff --git a/drivers/gpu/drm/i915/intel_dsi.c b/drivers/gpu/drm/i915/intel_dsi.c
index 8dc9a38..9e67f78 100644
--- a/drivers/gpu/drm/i915/intel_dsi.c
+++ b/drivers/gpu/drm/i915/intel_dsi.c
@@ -101,46 +101,59 @@ static void intel_dsi_pre_pll_enable(struct intel_encoder 
*encoder)
vlv_enable_dsi_pll(encoder);
  }

-static void intel_dsi_pre_enable(struct intel_encoder *encoder)
-{
-   DRM_DEBUG_KMS("\n");
-}
-
-static void intel_dsi_enable(struct intel_encoder *encoder)
+void intel_dsi_device_ready(struct intel_encoder *encoder)
  {
struct drm_i915_private *dev_priv = encoder->base.dev->dev_private;
struct intel_crtc *intel_crtc = to_intel_crtc(encoder->base.crtc);
struct intel_dsi *intel_dsi = enc_to_intel_dsi(&encoder->base);
int pipe = intel_crtc->pipe;
-   u32 temp;

DRM_DEBUG_KMS("\n");

if (intel_dsi->dev.dev_ops->panel_reset)
intel_dsi->dev.dev_ops->panel_reset(&intel_dsi->dev);

-   temp = I915_READ(MIPI_DEVICE_READY(pipe));
-   if ((temp & DEVICE_READY) == 0) {
-   temp &= ~ULPS_STATE_MASK;
-   I915_WRITE(MIPI_DEVICE_READY(pipe), temp | DEVICE_READY);
-   } else if (temp & ULPS_STATE_MASK) {
-   temp &= ~ULPS_STATE_MASK;
-   I915_WRITE(MIPI_DEVICE_READY(pipe), temp | ULPS_STATE_EXIT);
-   /*
-* We need to ensure that there is a minimum of 1 ms time
-* available before clearing the UPLS exit state.
-*/
-   msleep(2);
-   I915_WRITE(MIPI_DEVICE_READY(pipe), temp);
-   }
+   I915_WRITE_BITS(MIPI_PORT_CTRL(pipe), LP_OUTPUT_HOLD, LP_OUTPUT_HOLD);
+   usleep_range(1000, 1500);
+   I915_WRITE_BITS(MIPI_DEVICE_READY(pipe), DEVICE_READY |
+   ULPS_STATE_EXIT, DEVICE_READY | ULPS_STATE_MASK);
+   usleep_range(2000, 2500);
+   I915_WRITE_BITS(MIPI_DEVICE_READY(pipe), DEVICE_READY,
+   DEVICE_READY | ULPS_STATE_MASK);
+   usleep_range(2000, 2500);
+   I915_WRITE_BITS(MIPI_DEVICE_READY(pipe), 0x00,
+   DEVICE_READY | ULPS_STATE_MASK);
+   usleep_range(2000, 2500);
+   I915_WRITE_BITS(MIPI_DEVICE_READY(pipe), DEVICE_READY,
+   DEVICE_READY | ULPS_STATE_MASK);


It seems like an odd dance, but if that's what the hw folks say, I guess
we'll just have to take their word for it...


Yeah, but I reconfirmed from HW team and this

[Intel-gfx] [PATCH v3 5/7] drm/i915: Reorganize the DSI enable/disable sequence

2013-12-09 Thread Shobhit Kumar
Basically ULPS handling during enable/disable has been moved to
pre_enable and post_disable phases. PLL and panel power disable
also has been moved to post_disable phase. The ULPS entry/exit
sequneces as suggested by HW team is as follows -

During enable time -
set DEVICE_READY --> Clear DEVICE_READY --> set DEVICE_READY

And during disable time to flush all FIFOs -
set ENTER_SLEEP --> EXIT_SLEEP --> ENTER_SLEEP

Also during disbale sequnece sub-encoder disable is moved to the end
after port is disabled.

v2: Based on comments from Ville
- Detailed epxlaination in the commit messgae
- Moved parameter changes out into another patch
- Backlight enabling will be a new patch

v3: Updated as per Jani's comments
- Removed the I915_WRITE_BITS as it is not needed
- Moved panel_reset and send_otp_cmds hooks to dsi_pre_enable
- Moved disable_panel_power hook to dsi_post_disable
- Replace hardcoding with AFE_LATCHOUT

Signed-off-by: Yogesh Mohan Marimuthu 
Signed-off-by: Shobhit Kumar 
---
 drivers/gpu/drm/i915/intel_dsi.c | 110 +++
 drivers/gpu/drm/i915/intel_dsi.h |   2 +
 2 files changed, 79 insertions(+), 33 deletions(-)

diff --git a/drivers/gpu/drm/i915/intel_dsi.c b/drivers/gpu/drm/i915/intel_dsi.c
index 1016e7b..01b9f3a 100644
--- a/drivers/gpu/drm/i915/intel_dsi.c
+++ b/drivers/gpu/drm/i915/intel_dsi.c
@@ -101,46 +101,57 @@ static void intel_dsi_pre_pll_enable(struct intel_encoder 
*encoder)
vlv_enable_dsi_pll(encoder);
 }
 
-static void intel_dsi_pre_enable(struct intel_encoder *encoder)
+void intel_dsi_device_ready(struct intel_encoder *encoder)
 {
+   struct drm_i915_private *dev_priv = encoder->base.dev->dev_private;
+   struct intel_crtc *intel_crtc = to_intel_crtc(encoder->base.crtc);
+   int pipe = intel_crtc->pipe;
+   u32 val;
+
DRM_DEBUG_KMS("\n");
-}
 
-static void intel_dsi_enable(struct intel_encoder *encoder)
+   val = I915_READ(MIPI_PORT_CTRL(pipe));
+   I915_WRITE(MIPI_PORT_CTRL(pipe), val | LP_OUTPUT_HOLD);
+   usleep_range(1000, 1500);
+   I915_WRITE(MIPI_DEVICE_READY(pipe), DEVICE_READY | ULPS_STATE_EXIT);
+   usleep_range(2000, 2500);
+   I915_WRITE(MIPI_DEVICE_READY(pipe), DEVICE_READY);
+   usleep_range(2000, 2500);
+   I915_WRITE(MIPI_DEVICE_READY(pipe), 0x00);
+   usleep_range(2000, 2500);
+   I915_WRITE(MIPI_DEVICE_READY(pipe), DEVICE_READY);
+   usleep_range(2000, 2500);
+}
+static void intel_dsi_pre_enable(struct intel_encoder *encoder)
 {
-   struct drm_i915_private *dev_priv = encoder->base.dev->dev_private;
-   struct intel_crtc *intel_crtc = to_intel_crtc(encoder->base.crtc);
struct intel_dsi *intel_dsi = enc_to_intel_dsi(&encoder->base);
-   int pipe = intel_crtc->pipe;
-   u32 temp;
 
DRM_DEBUG_KMS("\n");
 
if (intel_dsi->dev.dev_ops->panel_reset)
intel_dsi->dev.dev_ops->panel_reset(&intel_dsi->dev);
 
-   temp = I915_READ(MIPI_DEVICE_READY(pipe));
-   if ((temp & DEVICE_READY) == 0) {
-   temp &= ~ULPS_STATE_MASK;
-   I915_WRITE(MIPI_DEVICE_READY(pipe), temp | DEVICE_READY);
-   } else if (temp & ULPS_STATE_MASK) {
-   temp &= ~ULPS_STATE_MASK;
-   I915_WRITE(MIPI_DEVICE_READY(pipe), temp | ULPS_STATE_EXIT);
-   /*
-* We need to ensure that there is a minimum of 1 ms time
-* available before clearing the UPLS exit state.
-*/
-   msleep(2);
-   I915_WRITE(MIPI_DEVICE_READY(pipe), temp);
-   }
+   /* put device in ready state */
+   intel_dsi_device_ready(encoder);
 
if (intel_dsi->dev.dev_ops->send_otp_cmds)
intel_dsi->dev.dev_ops->send_otp_cmds(&intel_dsi->dev);
+}
+
+static void intel_dsi_enable(struct intel_encoder *encoder)
+{
+   struct drm_device *dev = encoder->base.dev;
+   struct drm_i915_private *dev_priv = dev->dev_private;
+   struct intel_crtc *intel_crtc = to_intel_crtc(encoder->base.crtc);
+   struct intel_dsi *intel_dsi = enc_to_intel_dsi(&encoder->base);
+   int pipe = intel_crtc->pipe;
+   u32 temp;
+
+   DRM_DEBUG_KMS("\n");
 
if (is_cmd_mode(intel_dsi))
I915_WRITE(MIPI_MAX_RETURN_PKT_SIZE(pipe), 8 * 4);
-
-   if (is_vid_mode(intel_dsi)) {
+   else {
msleep(20); /* XXX */
dpi_send_cmd(intel_dsi, TURN_ON);
msleep(100);
@@ -157,7 +168,8 @@ static void intel_dsi_enable(struct intel_encoder *encoder)
 
 static void intel_dsi_disable(struct intel_encoder *encoder)
 {
-   struct drm_i915_private *dev_priv = encoder->base.dev->dev_private;
+   struct drm_device *dev = encoder->base.dev;
+   struct drm_i915_private

[Intel-gfx] [PATCH v3 3/7] drm/i915: Compute dsi_clk from pixel clock

2013-12-09 Thread Shobhit Kumar
Pixel clock based calculation is recommended in the MIPI host controller
documentation

v2: Based on review comments from Jani and Ville
- Use dsi_clk in KHz rather than converting in Hz and back to MHz
- RR formula is retained though not used but return dsi_clk in KHz now
- Moved the m-n-p changes into a separate patch
- Removed the parameter check for intel_dsi->dsi_clock_freq. This will be
  bought back in if needed when appropriate panel drivers are done

v3: Removed the unused mnp calculation from static table

Signed-off-by: Vijayakumar Balakrishnan 
Signed-off-by: Shobhit Kumar 
Reviewed-by: Jani Nikula 
---
 drivers/gpu/drm/i915/intel_dsi_pll.c | 89 +---
 1 file changed, 31 insertions(+), 58 deletions(-)

diff --git a/drivers/gpu/drm/i915/intel_dsi_pll.c 
b/drivers/gpu/drm/i915/intel_dsi_pll.c
index 44279b2..0d1b17f 100644
--- a/drivers/gpu/drm/i915/intel_dsi_pll.c
+++ b/drivers/gpu/drm/i915/intel_dsi_pll.c
@@ -50,6 +50,8 @@ static const u32 lfsr_converts[] = {
71, 35  /* 91 - 92 */
 };
 
+#ifdef DSI_CLK_FROM_RR
+
 static u32 dsi_rr_formula(const struct drm_display_mode *mode,
  int pixel_format, int video_mode_format,
  int lane_count, bool eotp)
@@ -121,7 +123,7 @@ static u32 dsi_rr_formula(const struct drm_display_mode 
*mode,
 
/* the dsi clock is divided by 2 in the hardware to get dsi ddr clock */
dsi_bit_clock_hz = bytes_per_x_frames_x_lanes * 8;
-   dsi_clk = dsi_bit_clock_hz / (1000 * 1000);
+   dsi_clk = dsi_bit_clock_hz / 1000;
 
if (eotp && video_mode_format == VIDEO_MODE_BURST)
dsi_clk *= 2;
@@ -129,64 +131,37 @@ static u32 dsi_rr_formula(const struct drm_display_mode 
*mode,
return dsi_clk;
 }
 
-#ifdef MNP_FROM_TABLE
-
-struct dsi_clock_table {
-   u32 freq;
-   u8 m;
-   u8 p;
-};
-
-static const struct dsi_clock_table dsi_clk_tbl[] = {
-   {300, 72, 6}, {313, 75, 6}, {323, 78, 6}, {333, 80, 6},
-   {343, 82, 6}, {353, 85, 6}, {363, 87, 6}, {373, 90, 6},
-   {383, 92, 6}, {390, 78, 5}, {393, 79, 5}, {400, 80, 5},
-   {401, 80, 5}, {402, 80, 5}, {403, 81, 5}, {404, 81, 5},
-   {405, 81, 5}, {406, 81, 5}, {407, 81, 5}, {408, 82, 5},
-   {409, 82, 5}, {410, 82, 5}, {411, 82, 5}, {412, 82, 5},
-   {413, 83, 5}, {414, 83, 5}, {415, 83, 5}, {416, 83, 5},
-   {417, 83, 5}, {418, 84, 5}, {419, 84, 5}, {420, 84, 5},
-   {430, 86, 5}, {440, 88, 5}, {450, 90, 5}, {460, 92, 5},
-   {470, 75, 4}, {480, 77, 4}, {490, 78, 4}, {500, 80, 4},
-   {510, 82, 4}, {520, 83, 4}, {530, 85, 4}, {540, 86, 4},
-   {550, 88, 4}, {560, 90, 4}, {570, 91, 4}, {580, 70, 3},
-   {590, 71, 3}, {600, 72, 3}, {610, 73, 3}, {620, 74, 3},
-   {630, 76, 3}, {640, 77, 3}, {650, 78, 3}, {660, 79, 3},
-   {670, 80, 3}, {680, 82, 3}, {690, 83, 3}, {700, 84, 3},
-   {710, 85, 3}, {720, 86, 3}, {730, 88, 3}, {740, 89, 3},
-   {750, 90, 3}, {760, 91, 3}, {770, 92, 3}, {780, 62, 2},
-   {790, 63, 2}, {800, 64, 2}, {880, 70, 2}, {900, 72, 2},
-   {1000, 80, 2},  /* dsi clock frequency in Mhz*/
-};
+#else
 
-static int dsi_calc_mnp(u32 dsi_clk, struct dsi_mnp *dsi_mnp)
+/* Get DSI clock from pixel clock */
+static u32 dsi_clk_from_pclk(const struct drm_display_mode *mode,
+ int pixel_format, int lane_count)
 {
-   unsigned int i;
-   u8 m;
-   u8 n;
-   u8 p;
-   u32 m_seed;
-
-   if (dsi_clk < 300 || dsi_clk > 1000)
-   return -ECHRNG;
+   u32 dsi_clk_khz;
+   u32 bpp;
 
-   for (i = 0; i <= ARRAY_SIZE(dsi_clk_tbl); i++) {
-   if (dsi_clk_tbl[i].freq > dsi_clk)
-   break;
+   switch (pixel_format) {
+   default:
+   case VID_MODE_FORMAT_RGB888:
+   case VID_MODE_FORMAT_RGB666_LOOSE:
+   bpp = 24;
+   break;
+   case VID_MODE_FORMAT_RGB666:
+   bpp = 18;
+   break;
+   case VID_MODE_FORMAT_RGB565:
+   bpp = 16;
+   break;
}
 
-   m = dsi_clk_tbl[i].m;
-   p = dsi_clk_tbl[i].p;
-   m_seed = lfsr_converts[m - 62];
-   n = 1;
-   dsi_mnp->dsi_pll_ctrl = 1 << (DSI_PLL_P1_POST_DIV_SHIFT + p - 2);
-   dsi_mnp->dsi_pll_div = (n - 1) << DSI_PLL_N1_DIV_SHIFT |
-   m_seed << DSI_PLL_M1_DIV_SHIFT;
+   /* DSI data rate = pixel clock * bits per pixel / lane count
+  pixel clock is converted from KHz to Hz */
+   dsi_clk_khz = DIV_ROUND_CLOSEST(mode->clock * bpp, lane_count);
 
-   return 0;
+   return dsi_clk_khz;
 }
 
-#else
+#endif
 
 static int dsi_calc_mnp(u32 dsi_clk, struct dsi_mnp *dsi_mnp)
 {
@@ -200,13 +175,14 @@ static int dsi_calc_mnp(u32 dsi_clk, struct dsi_mnp 
*dsi_mnp)
u32 calc_p;
u32 m_s

[Intel-gfx] [PATCH v3 7/7] drm/i915: Parametrize the dphy and other spec specific parameters

2013-12-09 Thread Shobhit Kumar
The values of these parameters will be different for differnet panel
based on dsi rate, lane count, etc. Remove the hardcodings and make
these as parameters whch will be initialized in panel specific
sub-encoder implementaion.

This will also form groundwork for planned generic panel sub-encoder
implemntation based on VBT design enhancments to support multiple panels

v2: Mask away the port_bits before use

Signed-off-by: Shobhit Kumar 
Reviewed-by: Jani Nikula 
---
 drivers/gpu/drm/i915/intel_dsi.c | 29 ++---
 drivers/gpu/drm/i915/intel_dsi.h | 14 ++
 2 files changed, 28 insertions(+), 15 deletions(-)

diff --git a/drivers/gpu/drm/i915/intel_dsi.c b/drivers/gpu/drm/i915/intel_dsi.c
index 10fb7be..d90a0e6 100644
--- a/drivers/gpu/drm/i915/intel_dsi.c
+++ b/drivers/gpu/drm/i915/intel_dsi.c
@@ -157,7 +157,8 @@ static void intel_dsi_enable(struct intel_encoder *encoder)
msleep(100);
 
/* assert ip_tg_enable signal */
-   temp = I915_READ(MIPI_PORT_CTRL(pipe));
+   temp = I915_READ(MIPI_PORT_CTRL(pipe)) & 
~LANE_CONFIGURATION_MASK;
+   temp = temp | intel_dsi->port_bits;
I915_WRITE(MIPI_PORT_CTRL(pipe), temp | DPI_ENABLE);
POSTING_READ(MIPI_PORT_CTRL(pipe));
}
@@ -391,11 +392,7 @@ static void intel_dsi_mode_set(struct intel_encoder 
*intel_encoder)
I915_WRITE(MIPI_INTR_STAT(pipe), 0x);
I915_WRITE(MIPI_INTR_EN(pipe), 0x);
 
-   I915_WRITE(MIPI_DPHY_PARAM(pipe),
-  0x3c << EXIT_ZERO_COUNT_SHIFT |
-  0x1f << TRAIL_COUNT_SHIFT |
-  0xc5 << CLK_ZERO_COUNT_SHIFT |
-  0x1f << PREPARE_COUNT_SHIFT);
+   I915_WRITE(MIPI_DPHY_PARAM(pipe), intel_dsi->dphy_reg);
 
I915_WRITE(MIPI_DPI_RESOLUTION(pipe),
   adjusted_mode->vdisplay << VERTICAL_ADDRESS_SHIFT |
@@ -443,9 +440,9 @@ static void intel_dsi_mode_set(struct intel_encoder 
*intel_encoder)
   adjusted_mode->htotal,
   bpp, intel_dsi->lane_count) + 1);
}
-   I915_WRITE(MIPI_LP_RX_TIMEOUT(pipe), 8309); /* max */
-   I915_WRITE(MIPI_TURN_AROUND_TIMEOUT(pipe), 0x14); /* max */
-   I915_WRITE(MIPI_DEVICE_RESET_TIMER(pipe), 0x); /* max */
+   I915_WRITE(MIPI_LP_RX_TIMEOUT(pipe), intel_dsi->lp_rx_timeout);
+   I915_WRITE(MIPI_TURN_AROUND_TIMEOUT(pipe), intel_dsi->turn_arnd_val);
+   I915_WRITE(MIPI_DEVICE_RESET_TIMER(pipe), intel_dsi->rst_timer_val);
 
/* dphy stuff */
 
@@ -460,29 +457,31 @@ static void intel_dsi_mode_set(struct intel_encoder 
*intel_encoder)
 *
 * XXX: write MIPI_STOP_STATE_STALL?
 */
-   I915_WRITE(MIPI_HIGH_LOW_SWITCH_COUNT(pipe), 0x46);
+   I915_WRITE(MIPI_HIGH_LOW_SWITCH_COUNT(pipe),
+   intel_dsi->hs_to_lp_count);
 
/* XXX: low power clock equivalence in terms of byte clock. the number
 * of byte clocks occupied in one low power clock. based on txbyteclkhs
 * and txclkesc. txclkesc time / txbyteclk time * (105 +
 * MIPI_STOP_STATE_STALL) / 105.???
 */
-   I915_WRITE(MIPI_LP_BYTECLK(pipe), 4);
+   I915_WRITE(MIPI_LP_BYTECLK(pipe), intel_dsi->lp_byte_clk);
 
/* the bw essential for transmitting 16 long packets containing 252
 * bytes meant for dcs write memory command is programmed in this
 * register in terms of byte clocks. based on dsi transfer rate and the
 * number of lanes configured the time taken to transmit 16 long packets
 * in a dsi stream varies. */
-   I915_WRITE(MIPI_DBI_BW_CTRL(pipe), 0x820);
+   I915_WRITE(MIPI_DBI_BW_CTRL(pipe), intel_dsi->bw_timer);
 
I915_WRITE(MIPI_CLK_LANE_SWITCH_TIME_CNT(pipe),
-  0xa << LP_HS_SSW_CNT_SHIFT |
-  0x14 << HS_LP_PWR_SW_CNT_SHIFT);
+  intel_dsi->clk_lp_to_hs_count << LP_HS_SSW_CNT_SHIFT |
+  intel_dsi->clk_hs_to_lp_count << HS_LP_PWR_SW_CNT_SHIFT);
 
if (is_vid_mode(intel_dsi))
I915_WRITE(MIPI_VIDEO_MODE_FORMAT(pipe),
-  intel_dsi->video_mode_format);
+   intel_dsi->video_frmt_cfg_bits |
+   intel_dsi->video_mode_format);
 }
 
 static enum drm_connector_status
diff --git a/drivers/gpu/drm/i915/intel_dsi.h b/drivers/gpu/drm/i915/intel_dsi.h
index 387dfe1..b4a27ce 100644
--- a/drivers/gpu/drm/i915/intel_dsi.h
+++ b/drivers/gpu/drm/i915/intel_dsi.h
@@ -96,6 +96,20 @@ struct intel_dsi {
 
/* eot for MIPI_EOT_DISABLE register */
u32 eot_disable;
+
+   u32 port_bits;
+   u32 bw_timer;
+   u32 dphy_reg;
+   u32 video_frmt_cfg_bits;
+   u16

[Intel-gfx] [PATCH v3 2/7] drm/i915: Use FLISDSI interface for band gap reset

2013-12-09 Thread Shobhit Kumar
v2: Rebased on latest code

Signed-off-by: Shobhit Kumar 
Signed-off-by: Yogesh Mohan Marimuthu 
Reviewed-by: Jani Nikula
---
 drivers/gpu/drm/i915/i915_drv.h   |  2 ++
 drivers/gpu/drm/i915/i915_reg.h   |  1 +
 drivers/gpu/drm/i915/intel_dsi.c  | 47 ++-
 drivers/gpu/drm/i915/intel_sideband.c | 14 +++
 4 files changed, 25 insertions(+), 39 deletions(-)

diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h
index 64ed8f4..4bcf1d4 100644
--- a/drivers/gpu/drm/i915/i915_drv.h
+++ b/drivers/gpu/drm/i915/i915_drv.h
@@ -2467,6 +2467,8 @@ u32 intel_sbi_read(struct drm_i915_private *dev_priv, u16 
reg,
   enum intel_sbi_destination destination);
 void intel_sbi_write(struct drm_i915_private *dev_priv, u16 reg, u32 value,
 enum intel_sbi_destination destination);
+u32 vlv_flisdsi_read(struct drm_i915_private *dev_priv, u32 reg);
+void vlv_flisdsi_write(struct drm_i915_private *dev_priv, u32 reg, u32 val);
 
 int vlv_gpu_freq(struct drm_i915_private *dev_priv, int val);
 int vlv_freq_opcode(struct drm_i915_private *dev_priv, int val);
diff --git a/drivers/gpu/drm/i915/i915_reg.h b/drivers/gpu/drm/i915/i915_reg.h
index 3be449d..5233749 100644
--- a/drivers/gpu/drm/i915/i915_reg.h
+++ b/drivers/gpu/drm/i915/i915_reg.h
@@ -362,6 +362,7 @@
 #define   IOSF_PORT_CCK0x14
 #define   IOSF_PORT_CCU0xA9
 #define   IOSF_PORT_GPS_CORE   0x48
+#define   IOSF_PORT_FLISDSI0x1B
 #define VLV_IOSF_DATA  (VLV_DISPLAY_BASE + 0x2104)
 #define VLV_IOSF_ADDR  (VLV_DISPLAY_BASE + 0x2108)
 
diff --git a/drivers/gpu/drm/i915/intel_dsi.c b/drivers/gpu/drm/i915/intel_dsi.c
index 42ed28a..1016e7b 100644
--- a/drivers/gpu/drm/i915/intel_dsi.c
+++ b/drivers/gpu/drm/i915/intel_dsi.c
@@ -37,49 +37,18 @@
 static const struct intel_dsi_device intel_dsi_devices[] = {
 };
 
-
-static void vlv_cck_modify(struct drm_i915_private *dev_priv, u32 reg, u32 val,
-  u32 mask)
-{
-   u32 tmp = vlv_cck_read(dev_priv, reg);
-   tmp &= ~mask;
-   tmp |= val;
-   vlv_cck_write(dev_priv, reg, tmp);
-}
-
-static void band_gap_wa(struct drm_i915_private *dev_priv)
+static void band_gap_reset(struct drm_i915_private *dev_priv)
 {
mutex_lock(&dev_priv->dpio_lock);
 
-   /* Enable bandgap fix in GOP driver */
-   vlv_cck_modify(dev_priv, 0x6D, 0x0001, 0x0003);
-   msleep(20);
-   vlv_cck_modify(dev_priv, 0x6E, 0x0001, 0x0003);
-   msleep(20);
-   vlv_cck_modify(dev_priv, 0x6F, 0x0001, 0x0003);
-   msleep(20);
-   vlv_cck_modify(dev_priv, 0x00, 0x8000, 0x8000);
-   msleep(20);
-   vlv_cck_modify(dev_priv, 0x00, 0x, 0x8000);
-   msleep(20);
-
-   /* Turn Display Trunk on */
-   vlv_cck_modify(dev_priv, 0x6B, 0x0002, 0x0003);
-   msleep(20);
-
-   vlv_cck_modify(dev_priv, 0x6C, 0x0002, 0x0003);
-   msleep(20);
-
-   vlv_cck_modify(dev_priv, 0x6D, 0x0002, 0x0003);
-   msleep(20);
-   vlv_cck_modify(dev_priv, 0x6E, 0x0002, 0x0003);
-   msleep(20);
-   vlv_cck_modify(dev_priv, 0x6F, 0x0002, 0x0003);
+   vlv_flisdsi_write(dev_priv, 0x08, 0x0001);
+   vlv_flisdsi_write(dev_priv, 0x0F, 0x0005);
+   vlv_flisdsi_write(dev_priv, 0x0F, 0x0025);
+   udelay(150);
+   vlv_flisdsi_write(dev_priv, 0x0F, 0x);
+   vlv_flisdsi_write(dev_priv, 0x08, 0x);
 
mutex_unlock(&dev_priv->dpio_lock);
-
-   /* Need huge delay, otherwise clock is not stable */
-   msleep(100);
 }
 
 static struct intel_dsi *intel_attached_dsi(struct drm_connector *connector)
@@ -364,7 +333,7 @@ static void intel_dsi_mode_set(struct intel_encoder 
*intel_encoder)
vlv_enable_dsi_pll(intel_encoder);
 
/* XXX: Location of the call */
-   band_gap_wa(dev_priv);
+   band_gap_reset(dev_priv);
 
/* escape clock divider, 20MHz, shared for A and C. device ready must be
 * off when doing this! txclkesc? */
diff --git a/drivers/gpu/drm/i915/intel_sideband.c 
b/drivers/gpu/drm/i915/intel_sideband.c
index cc6fbcd..0954f13 100644
--- a/drivers/gpu/drm/i915/intel_sideband.c
+++ b/drivers/gpu/drm/i915/intel_sideband.c
@@ -249,3 +249,17 @@ void intel_sbi_write(struct drm_i915_private *dev_priv, 
u16 reg, u32 value,
return;
}
 }
+
+u32 vlv_flisdsi_read(struct drm_i915_private *dev_priv, u32 reg)
+{
+   u32 val = 0;
+   vlv_sideband_rw(dev_priv, DPIO_DEVFN, IOSF_PORT_FLISDSI,
+   DPIO_OPCODE_REG_READ, reg, &val);
+   return val;
+}
+
+void vlv_flisdsi_write(struct drm_i915_private *dev_priv, u32 reg, u32 val)
+{
+   vlv_sideband_rw(dev_priv, DPIO_DE

[Intel-gfx] [PATCH v3 1/7] drm/i915: Add more dev ops for MIPI sub encoder

2013-12-09 Thread Shobhit Kumar
Some panels require one time programming if they do not contain their
own eeprom for basic register initialization. The sequence is

Panel Reset --> Send OTP --> Enable Pixel Stream --> Enable the panel

v2: Based on review comments from Jani and Ville
- Updated the commit message with more details
- Move the new parameters out of this patch

Signed-off-by: Yogesh Mohan Marimuthu 
Signed-off-by: Shobhit Kumar 
---
 drivers/gpu/drm/i915/intel_dsi.c | 9 -
 drivers/gpu/drm/i915/intel_dsi.h | 5 +
 2 files changed, 13 insertions(+), 1 deletion(-)

diff --git a/drivers/gpu/drm/i915/intel_dsi.c b/drivers/gpu/drm/i915/intel_dsi.c
index 7b9b350..42ed28a 100644
--- a/drivers/gpu/drm/i915/intel_dsi.c
+++ b/drivers/gpu/drm/i915/intel_dsi.c
@@ -147,6 +147,9 @@ static void intel_dsi_enable(struct intel_encoder *encoder)
 
DRM_DEBUG_KMS("\n");
 
+   if (intel_dsi->dev.dev_ops->panel_reset)
+   intel_dsi->dev.dev_ops->panel_reset(&intel_dsi->dev);
+
temp = I915_READ(MIPI_DEVICE_READY(pipe));
if ((temp & DEVICE_READY) == 0) {
temp &= ~ULPS_STATE_MASK;
@@ -162,6 +165,9 @@ static void intel_dsi_enable(struct intel_encoder *encoder)
I915_WRITE(MIPI_DEVICE_READY(pipe), temp);
}
 
+   if (intel_dsi->dev.dev_ops->send_otp_cmds)
+   intel_dsi->dev.dev_ops->send_otp_cmds(&intel_dsi->dev);
+
if (is_cmd_mode(intel_dsi))
I915_WRITE(MIPI_MAX_RETURN_PKT_SIZE(pipe), 8 * 4);
 
@@ -176,7 +182,8 @@ static void intel_dsi_enable(struct intel_encoder *encoder)
POSTING_READ(MIPI_PORT_CTRL(pipe));
}
 
-   intel_dsi->dev.dev_ops->enable(&intel_dsi->dev);
+   if (intel_dsi->dev.dev_ops->enable)
+   intel_dsi->dev.dev_ops->enable(&intel_dsi->dev);
 }
 
 static void intel_dsi_disable(struct intel_encoder *encoder)
diff --git a/drivers/gpu/drm/i915/intel_dsi.h b/drivers/gpu/drm/i915/intel_dsi.h
index c7765f3..14509d6 100644
--- a/drivers/gpu/drm/i915/intel_dsi.h
+++ b/drivers/gpu/drm/i915/intel_dsi.h
@@ -39,6 +39,11 @@ struct intel_dsi_device {
 struct intel_dsi_dev_ops {
bool (*init)(struct intel_dsi_device *dsi);
 
+   void (*panel_reset)(struct intel_dsi_device *dsi);
+
+   /* one time programmable commands if needed */
+   void (*send_otp_cmds)(struct intel_dsi_device *dsi);
+
/* This callback must be able to assume DSI commands can be sent */
void (*enable)(struct intel_dsi_device *dsi);
 
-- 
1.8.3.2

___
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/intel-gfx


[Intel-gfx] [PATCH v3 0/7] drm/i915: Baytrail MIPI DSI support Updated

2013-12-09 Thread Shobhit Kumar
Hi All -
These patches enhance the current support for MIPI DSI for Baytrail. They
continue on the sub-encoder design and adds few more dev_ops to handle
sequence correctly. Major changes are -

1. DSI Clock calculation based on pixel clock
2. Add new dev_ops for better sequencing the enable/disable path
3. Parameterized the hardcoded DSI parameters. These also forms building
   block for the generic MIPI driver to come in future based on enhancements
   in VBT. All these parameters are initialized or computed in the sub-encoder
   driver. Some of them might look unneccesary for now.

I am also aware of the drm_bridge support now comming in and will in future
migrate from sub-encoder design to drm_bridge.

This DSI sequence has been validated with couple of test panels and is working 
now.
Still no sub-encoder driver is included and this support will be mostly be 
disabled
untill a panel sub-encoder driver is added. Proper detection or VBT is still 
pending.

v2: Mostly changes from review comments from Jani Nikula and Ville Syrjala
- Split the parameters into new patch
- Split the dsi_clk computation and m-n-p modification in separate patches
- The DSI sequence refactoring has been splitted into multiple patches and 
also
  few code changes are not needed after reworking/relooking at them and 
have been
  removed
- Backlight enabling has been removed as that depends on platform PMIC 
driver which
  is not yet there in upstream kernel. Will be added later.
- Other general code cleanup as suggested
- drm/i915: Use FLISDSI interface for band gap reset - has no changes and 
is included
  for completeness of the patch set

v3: Next round of changes resulting from Jani's review
- Removed the I915_WRITE_BITS as it was found that we need not do 
read/modify/write and
  can just write the value
- Moved the sub-encoder hook in dsi_pre_enable and dsi_post_enable
- Minor coding tidbits are fixed

Regards
Shobhit

Shobhit Kumar (7):
  drm/i915: Add more dev ops for MIPI sub encoder
  drm/i915: Use FLISDSI interface for band gap reset
  drm/i915: Compute dsi_clk from pixel clock
  drm/i915: Try harder to get best m,n,p values with minimal error
  drm/i915: Reorganize the DSI enable/disable sequence
  drm/i915: Remove redundant DSI PLL enabling
  drm/i915: Parametrize the dphy and other spec specific parameters

 drivers/gpu/drm/i915/i915_drv.h   |   2 +
 drivers/gpu/drm/i915/i915_reg.h   |   1 +
 drivers/gpu/drm/i915/intel_dsi.c  | 188 ++
 drivers/gpu/drm/i915/intel_dsi.h  |  21 
 drivers/gpu/drm/i915/intel_dsi_pll.c  | 119 +
 drivers/gpu/drm/i915/intel_sideband.c |  14 +++
 6 files changed, 191 insertions(+), 154 deletions(-)

-- 
1.8.3.2

___
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/intel-gfx


[Intel-gfx] [PATCH v3 6/7] drm/i915: Remove redundant DSI PLL enabling

2013-12-09 Thread Shobhit Kumar
DSI PLL will get configured during crtc_enable using ->pre_pll_enable
and no need to do in ->mode_set

Signed-off-by: Shobhit Kumar 
Reviewed-by: Jani Nikula 
---
 drivers/gpu/drm/i915/intel_dsi.c | 3 ---
 1 file changed, 3 deletions(-)

diff --git a/drivers/gpu/drm/i915/intel_dsi.c b/drivers/gpu/drm/i915/intel_dsi.c
index 01b9f3a..10fb7be 100644
--- a/drivers/gpu/drm/i915/intel_dsi.c
+++ b/drivers/gpu/drm/i915/intel_dsi.c
@@ -373,9 +373,6 @@ static void intel_dsi_mode_set(struct intel_encoder 
*intel_encoder)
 
DRM_DEBUG_KMS("pipe %c\n", pipe_name(pipe));
 
-   /* Update the DSI PLL */
-   vlv_enable_dsi_pll(intel_encoder);
-
/* XXX: Location of the call */
band_gap_reset(dev_priv);
 
-- 
1.8.3.2

___
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/intel-gfx


[Intel-gfx] [PATCH v3 4/7] drm/i915: Try harder to get best m, n, p values with minimal error

2013-12-09 Thread Shobhit Kumar
Basically check for both +ive and -ive deviation from target clock and
pick the one with minimal error. If we get a direct match, break from
loop to acheive some optimization.

v2: Use signed variable for target and calculated dsi clock values

Signed-off-by: Vijayakumar Balakrishnan 
Signed-off-by: Shobhit Kumar 
---
 drivers/gpu/drm/i915/intel_dsi_pll.c | 30 --
 1 file changed, 20 insertions(+), 10 deletions(-)

diff --git a/drivers/gpu/drm/i915/intel_dsi_pll.c 
b/drivers/gpu/drm/i915/intel_dsi_pll.c
index 0d1b17f..ba79ec1 100644
--- a/drivers/gpu/drm/i915/intel_dsi_pll.c
+++ b/drivers/gpu/drm/i915/intel_dsi_pll.c
@@ -169,8 +169,8 @@ static int dsi_calc_mnp(u32 dsi_clk, struct dsi_mnp 
*dsi_mnp)
u32 ref_clk;
u32 error;
u32 tmp_error;
-   u32 target_dsi_clk;
-   u32 calc_dsi_clk;
+   int target_dsi_clk;
+   int calc_dsi_clk;
u32 calc_m;
u32 calc_p;
u32 m_seed;
@@ -184,22 +184,32 @@ static int dsi_calc_mnp(u32 dsi_clk, struct dsi_mnp 
*dsi_mnp)
ref_clk = 25000;
target_dsi_clk = dsi_clk;
error = 0x;
+   tmp_error = 0x;
calc_m = 0;
calc_p = 0;
 
for (m = 62; m <= 92; m++) {
for (p = 2; p <= 6; p++) {
-
+   /* Find the optimal m and p divisors
+   with minimal error +/- the required clock */
calc_dsi_clk = (m * ref_clk) / p;
-   if (calc_dsi_clk >= target_dsi_clk) {
-   tmp_error = calc_dsi_clk - target_dsi_clk;
-   if (tmp_error < error) {
-   error = tmp_error;
-   calc_m = m;
-   calc_p = p;
-   }
+   if (calc_dsi_clk == target_dsi_clk) {
+   calc_m = m;
+   calc_p = p;
+   error = 0;
+   break;
+   } else
+   tmp_error = abs(target_dsi_clk - calc_dsi_clk);
+
+   if (tmp_error < error) {
+   error = tmp_error;
+   calc_m = m;
+   calc_p = p;
}
}
+
+   if (error == 0)
+   break;
}
 
m_seed = lfsr_converts[calc_m - 62];
-- 
1.8.3.2

___
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/intel-gfx


Re: [Intel-gfx] [PATCH v3 5/7] drm/i915: Reorganize the DSI enable/disable sequence

2013-12-11 Thread Shobhit Kumar



On Wednesday 11 December 2013 04:32 PM, Jani Nikula wrote:

On Tue, 10 Dec 2013, Shobhit Kumar  wrote:

Basically ULPS handling during enable/disable has been moved to
pre_enable and post_disable phases. PLL and panel power disable
also has been moved to post_disable phase. The ULPS entry/exit
sequneces as suggested by HW team is as follows -

During enable time -
set DEVICE_READY --> Clear DEVICE_READY --> set DEVICE_READY

And during disable time to flush all FIFOs -
set ENTER_SLEEP --> EXIT_SLEEP --> ENTER_SLEEP

Also during disbale sequnece sub-encoder disable is moved to the end
after port is disabled.

v2: Based on comments from Ville
 - Detailed epxlaination in the commit messgae
 - Moved parameter changes out into another patch
 - Backlight enabling will be a new patch

v3: Updated as per Jani's comments
 - Removed the I915_WRITE_BITS as it is not needed
 - Moved panel_reset and send_otp_cmds hooks to dsi_pre_enable
 - Moved disable_panel_power hook to dsi_post_disable
 - Replace hardcoding with AFE_LATCHOUT

Signed-off-by: Yogesh Mohan Marimuthu 
Signed-off-by: Shobhit Kumar 
---
  drivers/gpu/drm/i915/intel_dsi.c | 110 +++
  drivers/gpu/drm/i915/intel_dsi.h |   2 +
  2 files changed, 79 insertions(+), 33 deletions(-)

diff --git a/drivers/gpu/drm/i915/intel_dsi.c b/drivers/gpu/drm/i915/intel_dsi.c
index 1016e7b..01b9f3a 100644
--- a/drivers/gpu/drm/i915/intel_dsi.c
+++ b/drivers/gpu/drm/i915/intel_dsi.c
@@ -101,46 +101,57 @@ static void intel_dsi_pre_pll_enable(struct intel_encoder 
*encoder)
vlv_enable_dsi_pll(encoder);
  }

-static void intel_dsi_pre_enable(struct intel_encoder *encoder)
+void intel_dsi_device_ready(struct intel_encoder *encoder)


Should be static.


  {
+   struct drm_i915_private *dev_priv = encoder->base.dev->dev_private;
+   struct intel_crtc *intel_crtc = to_intel_crtc(encoder->base.crtc);
+   int pipe = intel_crtc->pipe;
+   u32 val;
+
DRM_DEBUG_KMS("\n");
-}

-static void intel_dsi_enable(struct intel_encoder *encoder)
+   val = I915_READ(MIPI_PORT_CTRL(pipe));
+   I915_WRITE(MIPI_PORT_CTRL(pipe), val | LP_OUTPUT_HOLD);
+   usleep_range(1000, 1500);
+   I915_WRITE(MIPI_DEVICE_READY(pipe), DEVICE_READY | ULPS_STATE_EXIT);
+   usleep_range(2000, 2500);
+   I915_WRITE(MIPI_DEVICE_READY(pipe), DEVICE_READY);
+   usleep_range(2000, 2500);
+   I915_WRITE(MIPI_DEVICE_READY(pipe), 0x00);
+   usleep_range(2000, 2500);
+   I915_WRITE(MIPI_DEVICE_READY(pipe), DEVICE_READY);
+   usleep_range(2000, 2500);
+}
+static void intel_dsi_pre_enable(struct intel_encoder *encoder)
  {
-   struct drm_i915_private *dev_priv = encoder->base.dev->dev_private;
-   struct intel_crtc *intel_crtc = to_intel_crtc(encoder->base.crtc);
struct intel_dsi *intel_dsi = enc_to_intel_dsi(&encoder->base);
-   int pipe = intel_crtc->pipe;
-   u32 temp;

DRM_DEBUG_KMS("\n");

if (intel_dsi->dev.dev_ops->panel_reset)
intel_dsi->dev.dev_ops->panel_reset(&intel_dsi->dev);

-   temp = I915_READ(MIPI_DEVICE_READY(pipe));
-   if ((temp & DEVICE_READY) == 0) {
-   temp &= ~ULPS_STATE_MASK;
-   I915_WRITE(MIPI_DEVICE_READY(pipe), temp | DEVICE_READY);
-   } else if (temp & ULPS_STATE_MASK) {
-   temp &= ~ULPS_STATE_MASK;
-   I915_WRITE(MIPI_DEVICE_READY(pipe), temp | ULPS_STATE_EXIT);
-   /*
-* We need to ensure that there is a minimum of 1 ms time
-* available before clearing the UPLS exit state.
-*/
-   msleep(2);
-   I915_WRITE(MIPI_DEVICE_READY(pipe), temp);
-   }
+   /* put device in ready state */
+   intel_dsi_device_ready(encoder);

if (intel_dsi->dev.dev_ops->send_otp_cmds)
intel_dsi->dev.dev_ops->send_otp_cmds(&intel_dsi->dev);
+}
+
+static void intel_dsi_enable(struct intel_encoder *encoder)
+{
+   struct drm_device *dev = encoder->base.dev;
+   struct drm_i915_private *dev_priv = dev->dev_private;
+   struct intel_crtc *intel_crtc = to_intel_crtc(encoder->base.crtc);
+   struct intel_dsi *intel_dsi = enc_to_intel_dsi(&encoder->base);
+   int pipe = intel_crtc->pipe;
+   u32 temp;
+
+   DRM_DEBUG_KMS("\n");

if (is_cmd_mode(intel_dsi))
I915_WRITE(MIPI_MAX_RETURN_PKT_SIZE(pipe), 8 * 4);
-
-   if (is_vid_mode(intel_dsi)) {
+   else {
msleep(20); /* XXX */
dpi_send_cmd(intel_dsi, TURN_ON);
msleep(100);
@@ -157,7 +168,8 @@ static void intel_dsi_enable(struct intel_encoder *encoder)

  static void intel_dsi_disable(struct intel_encoder *encoder)
  {
-   struct drm_i915_private *dev_

[Intel-gfx] [PATCH 5/7] drm/i915: Reorganize the DSI enable/disable sequence

2013-12-11 Thread Shobhit Kumar
Basically ULPS handling during enable/disable has been moved to
pre_enable and post_disable phases. PLL and panel power disable
also has been moved to post_disable phase. The ULPS entry/exit
sequneces as suggested by HW team is as follows -

During enable time -
set DEVICE_READY --> Clear DEVICE_READY --> set DEVICE_READY

And during disable time to flush all FIFOs -
set ENTER_SLEEP --> EXIT_SLEEP --> ENTER_SLEEP

Also during disbale sequnece sub-encoder disable is moved to the end
after port is disabled.

v2: Based on comments from Ville
- Detailed epxlaination in the commit messgae
- Moved parameter changes out into another patch
- Backlight enabling will be a new patch

v3: Updated as per Jani's comments
- Removed the I915_WRITE_BITS as it is not needed
- Moved panel_reset and send_otp_cmds hooks to dsi_pre_enable
- Moved disable_panel_power hook to dsi_post_disable
- Replace hardcoding with AFE_LATCHOUT

v4: Make intel_dsi_device_ready and intel_dsi_clear_device_ready static

Signed-off-by: Yogesh Mohan Marimuthu 
Signed-off-by: Shobhit Kumar 
Reviewed-by: Jani Nikula 
---
 drivers/gpu/drm/i915/intel_dsi.c | 110 +++
 drivers/gpu/drm/i915/intel_dsi.h |   2 +
 2 files changed, 79 insertions(+), 33 deletions(-)

diff --git a/drivers/gpu/drm/i915/intel_dsi.c b/drivers/gpu/drm/i915/intel_dsi.c
index 1016e7b..e9bcb46 100644
--- a/drivers/gpu/drm/i915/intel_dsi.c
+++ b/drivers/gpu/drm/i915/intel_dsi.c
@@ -101,46 +101,57 @@ static void intel_dsi_pre_pll_enable(struct intel_encoder 
*encoder)
vlv_enable_dsi_pll(encoder);
 }
 
-static void intel_dsi_pre_enable(struct intel_encoder *encoder)
+static void intel_dsi_device_ready(struct intel_encoder *encoder)
 {
+   struct drm_i915_private *dev_priv = encoder->base.dev->dev_private;
+   struct intel_crtc *intel_crtc = to_intel_crtc(encoder->base.crtc);
+   int pipe = intel_crtc->pipe;
+   u32 val;
+
DRM_DEBUG_KMS("\n");
-}
 
-static void intel_dsi_enable(struct intel_encoder *encoder)
+   val = I915_READ(MIPI_PORT_CTRL(pipe));
+   I915_WRITE(MIPI_PORT_CTRL(pipe), val | LP_OUTPUT_HOLD);
+   usleep_range(1000, 1500);
+   I915_WRITE(MIPI_DEVICE_READY(pipe), DEVICE_READY | ULPS_STATE_EXIT);
+   usleep_range(2000, 2500);
+   I915_WRITE(MIPI_DEVICE_READY(pipe), DEVICE_READY);
+   usleep_range(2000, 2500);
+   I915_WRITE(MIPI_DEVICE_READY(pipe), 0x00);
+   usleep_range(2000, 2500);
+   I915_WRITE(MIPI_DEVICE_READY(pipe), DEVICE_READY);
+   usleep_range(2000, 2500);
+}
+static void intel_dsi_pre_enable(struct intel_encoder *encoder)
 {
-   struct drm_i915_private *dev_priv = encoder->base.dev->dev_private;
-   struct intel_crtc *intel_crtc = to_intel_crtc(encoder->base.crtc);
struct intel_dsi *intel_dsi = enc_to_intel_dsi(&encoder->base);
-   int pipe = intel_crtc->pipe;
-   u32 temp;
 
DRM_DEBUG_KMS("\n");
 
if (intel_dsi->dev.dev_ops->panel_reset)
intel_dsi->dev.dev_ops->panel_reset(&intel_dsi->dev);
 
-   temp = I915_READ(MIPI_DEVICE_READY(pipe));
-   if ((temp & DEVICE_READY) == 0) {
-   temp &= ~ULPS_STATE_MASK;
-   I915_WRITE(MIPI_DEVICE_READY(pipe), temp | DEVICE_READY);
-   } else if (temp & ULPS_STATE_MASK) {
-   temp &= ~ULPS_STATE_MASK;
-   I915_WRITE(MIPI_DEVICE_READY(pipe), temp | ULPS_STATE_EXIT);
-   /*
-* We need to ensure that there is a minimum of 1 ms time
-* available before clearing the UPLS exit state.
-*/
-   msleep(2);
-   I915_WRITE(MIPI_DEVICE_READY(pipe), temp);
-   }
+   /* put device in ready state */
+   intel_dsi_device_ready(encoder);
 
if (intel_dsi->dev.dev_ops->send_otp_cmds)
intel_dsi->dev.dev_ops->send_otp_cmds(&intel_dsi->dev);
+}
+
+static void intel_dsi_enable(struct intel_encoder *encoder)
+{
+   struct drm_device *dev = encoder->base.dev;
+   struct drm_i915_private *dev_priv = dev->dev_private;
+   struct intel_crtc *intel_crtc = to_intel_crtc(encoder->base.crtc);
+   struct intel_dsi *intel_dsi = enc_to_intel_dsi(&encoder->base);
+   int pipe = intel_crtc->pipe;
+   u32 temp;
+
+   DRM_DEBUG_KMS("\n");
 
if (is_cmd_mode(intel_dsi))
I915_WRITE(MIPI_MAX_RETURN_PKT_SIZE(pipe), 8 * 4);
-
-   if (is_vid_mode(intel_dsi)) {
+   else {
msleep(20); /* XXX */
dpi_send_cmd(intel_dsi, TURN_ON);
msleep(100);
@@ -157,7 +168,8 @@ static void intel_dsi_enable(struct intel_encoder *encoder)
 
 static void intel_dsi_disable(struct intel_encoder *encoder)
 {
-   struct drm_i915_private *dev_priv = encoder->base.dev

Re: [Intel-gfx] [PATCH 5/7] drm/i915: Reorganize the DSI enable/disable sequence

2013-12-11 Thread Shobhit Kumar

On Wednesday 11 December 2013 06:36 PM, Daniel Vetter wrote:

On Wed, Dec 11, 2013 at 05:52:05PM +0530, Shobhit Kumar wrote:

Basically ULPS handling during enable/disable has been moved to
pre_enable and post_disable phases. PLL and panel power disable
also has been moved to post_disable phase. The ULPS entry/exit
sequneces as suggested by HW team is as follows -

During enable time -
set DEVICE_READY --> Clear DEVICE_READY --> set DEVICE_READY

And during disable time to flush all FIFOs -
set ENTER_SLEEP --> EXIT_SLEEP --> ENTER_SLEEP

Also during disbale sequnece sub-encoder disable is moved to the end
after port is disabled.

v2: Based on comments from Ville
 - Detailed epxlaination in the commit messgae
 - Moved parameter changes out into another patch
 - Backlight enabling will be a new patch

v3: Updated as per Jani's comments
 - Removed the I915_WRITE_BITS as it is not needed
 - Moved panel_reset and send_otp_cmds hooks to dsi_pre_enable
 - Moved disable_panel_power hook to dsi_post_disable
 - Replace hardcoding with AFE_LATCHOUT

v4: Make intel_dsi_device_ready and intel_dsi_clear_device_ready static

Signed-off-by: Yogesh Mohan Marimuthu 
Signed-off-by: Shobhit Kumar 
Reviewed-by: Jani Nikula 


Merged all patches from this series, thanks. btw, when resending
individual patches pls use the --in-reply-to option so that they're all
nicely grouped together with the discussion.



Thanks Daniel for merging and the tip.

Regards
Shobhit
___
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/intel-gfx


[Intel-gfx] [PATCH 0/4] drm/i915: Baytrail MIPI DSI support Updated

2013-10-21 Thread Shobhit Kumar
Hi All - 
These patches enhance the current support for MIPI DSI for Baytrail. They
continue on the sub-encoder design and adds few more dev_ops to handle
sequence correctly. Major changes are -
 1. DSI Clock calculation based on pixel clock
 2. Add new dev_ops for better sequencing the enable/disable path
 3. Parameterized the hardcoded DSI parameters. These also forms building
block for the generic MIPI driver to come in future based on enhancements
in VBT. All these parameters are initialized or computed in the sub-encoder
driver. Some of them might look unneccesary for now.

I am also aware of the drm_bridge support now comming in and will in future
migrate from sub-encoder design to drm_bridge.

This DSI sequence has been validated with couple of test panels and is working 
now.
Still no sub-encoder driver is included and this support will be mostly be 
disabled
untill a panel sub-encoder driver is added. Proper detection or VBT is still 
pending.

Regards
Shobhit

Shobhit Kumar (4):
  drm/i915: Add more dev ops for MIPI sub encoder
  drm/i915: Use FLISDSI interface for band gap reset
  drm/i915: Compute dsi_clk from pixel clock
  drm/i915: Parameterize the MIPI enabling sequnece and adjust the
sequence

 drivers/gpu/drm/i915/i915_drv.h   |   13 ++
 drivers/gpu/drm/i915/i915_reg.h   |1 +
 drivers/gpu/drm/i915/intel_dsi.c  |  378 +
 drivers/gpu/drm/i915/intel_dsi.h  |   29 +++
 drivers/gpu/drm/i915/intel_dsi_pll.c  |   75 +--
 drivers/gpu/drm/i915/intel_sideband.c |   14 ++
 6 files changed, 318 insertions(+), 192 deletions(-)

-- 
1.7.9.5

___
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/intel-gfx


[Intel-gfx] [PATCH 1/4] drm/i915: Add more dev ops for MIPI sub encoder

2013-10-21 Thread Shobhit Kumar
Also add new fields in intel_dsi to have all dphy related parameters.
These will be useful even when we go for pure generic MIPI design

Yogesh Mohan Marimuthu 
Signed-off-by: Shobhit Kumar 
---
 drivers/gpu/drm/i915/intel_dsi.c |9 -
 drivers/gpu/drm/i915/intel_dsi.h |   29 +
 2 files changed, 37 insertions(+), 1 deletion(-)

diff --git a/drivers/gpu/drm/i915/intel_dsi.c b/drivers/gpu/drm/i915/intel_dsi.c
index 9a2fdd2..34e19b7 100644
--- a/drivers/gpu/drm/i915/intel_dsi.c
+++ b/drivers/gpu/drm/i915/intel_dsi.c
@@ -147,6 +147,9 @@ static void intel_dsi_enable(struct intel_encoder *encoder)
 
DRM_DEBUG_KMS("\n");
 
+   if (intel_dsi->dev.dev_ops->panel_reset)
+   intel_dsi->dev.dev_ops->panel_reset(&intel_dsi->dev);
+
temp = I915_READ(MIPI_DEVICE_READY(pipe));
if ((temp & DEVICE_READY) == 0) {
temp &= ~ULPS_STATE_MASK;
@@ -162,6 +165,9 @@ static void intel_dsi_enable(struct intel_encoder *encoder)
I915_WRITE(MIPI_DEVICE_READY(pipe), temp);
}
 
+   if (intel_dsi->dev.dev_ops->send_otp_cmds)
+   intel_dsi->dev.dev_ops->send_otp_cmds(&intel_dsi->dev);
+
if (is_cmd_mode(intel_dsi))
I915_WRITE(MIPI_MAX_RETURN_PKT_SIZE(pipe), 8 * 4);
 
@@ -176,7 +182,8 @@ static void intel_dsi_enable(struct intel_encoder *encoder)
POSTING_READ(MIPI_PORT_CTRL(pipe));
}
 
-   intel_dsi->dev.dev_ops->enable(&intel_dsi->dev);
+   if (intel_dsi->dev.dev_ops->enable)
+   intel_dsi->dev.dev_ops->enable(&intel_dsi->dev);
 }
 
 static void intel_dsi_disable(struct intel_encoder *encoder)
diff --git a/drivers/gpu/drm/i915/intel_dsi.h b/drivers/gpu/drm/i915/intel_dsi.h
index c7765f3..b71c9b3 100644
--- a/drivers/gpu/drm/i915/intel_dsi.h
+++ b/drivers/gpu/drm/i915/intel_dsi.h
@@ -39,6 +39,13 @@ struct intel_dsi_device {
 struct intel_dsi_dev_ops {
bool (*init)(struct intel_dsi_device *dsi);
 
+   void (*panel_reset)(struct intel_dsi_device *dsi);
+
+   void (*disable_panel_power)(struct intel_dsi_device *dsi);
+
+   /* send one time programmable commands */
+   void (*send_otp_cmds)(struct intel_dsi_device *dsi);
+
/* This callback must be able to assume DSI commands can be sent */
void (*enable)(struct intel_dsi_device *dsi);
 
@@ -89,6 +96,28 @@ struct intel_dsi {
 
/* eot for MIPI_EOT_DISABLE register */
u32 eot_disable;
+
+   u16 dsi_clock_freq;
+   u8 video_mode_type;
+   u32 data_width;
+   u8 dither;
+   u32 port_bits;
+   u8 escape_clk_div;
+   u32 lp_rx_timeout;
+   u8 turn_arnd_val;
+   u16 init_count;
+   u16 rst_timer_val;
+   u16 hs_to_lp_count;
+   u16 lp_byte_clk;
+   u32 bw_timer;
+   u16 clk_lp_to_hs_count;
+   u16 clk_hs_to_lp_count;
+   u32 video_frmt_cfg_bits;
+   u32 dphy_reg;
+
+   u8 backlight_off_delay; /*in ms*/
+   bool send_shutdown;
+   u8 shutdown_pkt_delay; /*in ms*/
 };
 
 static inline struct intel_dsi *enc_to_intel_dsi(struct drm_encoder *encoder)
-- 
1.7.9.5

___
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/intel-gfx


[Intel-gfx] [PATCH 2/4] drm/i915: Use FLISDSI interface for band gap reset

2013-10-21 Thread Shobhit Kumar
Signed-off-by: Shobhit Kumar 
Signed-off-by: Yogesh Mohan Marimuthu 
---
 drivers/gpu/drm/i915/i915_drv.h   |2 ++
 drivers/gpu/drm/i915/i915_reg.h   |1 +
 drivers/gpu/drm/i915/intel_dsi.c  |   47 ++---
 drivers/gpu/drm/i915/intel_sideband.c |   14 ++
 4 files changed, 25 insertions(+), 39 deletions(-)

diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h
index faf4dc1..1c42bb4 100644
--- a/drivers/gpu/drm/i915/i915_drv.h
+++ b/drivers/gpu/drm/i915/i915_drv.h
@@ -2334,6 +2334,8 @@ u32 intel_sbi_read(struct drm_i915_private *dev_priv, u16 
reg,
   enum intel_sbi_destination destination);
 void intel_sbi_write(struct drm_i915_private *dev_priv, u16 reg, u32 value,
 enum intel_sbi_destination destination);
+u32 vlv_flisdsi_read(struct drm_i915_private *dev_priv, u32 reg);
+void vlv_flisdsi_write(struct drm_i915_private *dev_priv, u32 reg, u32 val);
 
 int vlv_gpu_freq(int ddr_freq, int val);
 int vlv_freq_opcode(int ddr_freq, int val);
diff --git a/drivers/gpu/drm/i915/i915_reg.h b/drivers/gpu/drm/i915/i915_reg.h
index 852d3c4..172f490 100644
--- a/drivers/gpu/drm/i915/i915_reg.h
+++ b/drivers/gpu/drm/i915/i915_reg.h
@@ -355,6 +355,7 @@
 #define   IOSF_PORT_CCK0x14
 #define   IOSF_PORT_CCU0xA9
 #define   IOSF_PORT_GPS_CORE   0x48
+#define   IOSF_PORT_FLISDSI0x1B
 #define VLV_IOSF_DATA  (VLV_DISPLAY_BASE + 0x2104)
 #define VLV_IOSF_ADDR  (VLV_DISPLAY_BASE + 0x2108)
 
diff --git a/drivers/gpu/drm/i915/intel_dsi.c b/drivers/gpu/drm/i915/intel_dsi.c
index 34e19b7..5a9dbfd 100644
--- a/drivers/gpu/drm/i915/intel_dsi.c
+++ b/drivers/gpu/drm/i915/intel_dsi.c
@@ -37,49 +37,18 @@
 static const struct intel_dsi_device intel_dsi_devices[] = {
 };
 
-
-static void vlv_cck_modify(struct drm_i915_private *dev_priv, u32 reg, u32 val,
-  u32 mask)
-{
-   u32 tmp = vlv_cck_read(dev_priv, reg);
-   tmp &= ~mask;
-   tmp |= val;
-   vlv_cck_write(dev_priv, reg, tmp);
-}
-
-static void band_gap_wa(struct drm_i915_private *dev_priv)
+static void band_gap_reset(struct drm_i915_private *dev_priv)
 {
mutex_lock(&dev_priv->dpio_lock);
 
-   /* Enable bandgap fix in GOP driver */
-   vlv_cck_modify(dev_priv, 0x6D, 0x0001, 0x0003);
-   msleep(20);
-   vlv_cck_modify(dev_priv, 0x6E, 0x0001, 0x0003);
-   msleep(20);
-   vlv_cck_modify(dev_priv, 0x6F, 0x0001, 0x0003);
-   msleep(20);
-   vlv_cck_modify(dev_priv, 0x00, 0x8000, 0x8000);
-   msleep(20);
-   vlv_cck_modify(dev_priv, 0x00, 0x, 0x8000);
-   msleep(20);
-
-   /* Turn Display Trunk on */
-   vlv_cck_modify(dev_priv, 0x6B, 0x0002, 0x0003);
-   msleep(20);
-
-   vlv_cck_modify(dev_priv, 0x6C, 0x0002, 0x0003);
-   msleep(20);
-
-   vlv_cck_modify(dev_priv, 0x6D, 0x0002, 0x0003);
-   msleep(20);
-   vlv_cck_modify(dev_priv, 0x6E, 0x0002, 0x0003);
-   msleep(20);
-   vlv_cck_modify(dev_priv, 0x6F, 0x0002, 0x0003);
+   vlv_flisdsi_write(dev_priv, 0x08, 0x0001);
+   vlv_flisdsi_write(dev_priv, 0x0F, 0x0005);
+   vlv_flisdsi_write(dev_priv, 0x0F, 0x0025);
+   udelay(150);
+   vlv_flisdsi_write(dev_priv, 0x0F, 0x);
+   vlv_flisdsi_write(dev_priv, 0x08, 0x);
 
mutex_unlock(&dev_priv->dpio_lock);
-
-   /* Need huge delay, otherwise clock is not stable */
-   msleep(100);
 }
 
 static struct intel_dsi *intel_attached_dsi(struct drm_connector *connector)
@@ -363,7 +332,7 @@ static void intel_dsi_mode_set(struct intel_encoder 
*intel_encoder)
vlv_enable_dsi_pll(intel_encoder);
 
/* XXX: Location of the call */
-   band_gap_wa(dev_priv);
+   band_gap_reset(dev_priv);
 
/* escape clock divider, 20MHz, shared for A and C. device ready must be
 * off when doing this! txclkesc? */
diff --git a/drivers/gpu/drm/i915/intel_sideband.c 
b/drivers/gpu/drm/i915/intel_sideband.c
index acd1cfe..e3f5210 100644
--- a/drivers/gpu/drm/i915/intel_sideband.c
+++ b/drivers/gpu/drm/i915/intel_sideband.c
@@ -239,3 +239,17 @@ void intel_sbi_write(struct drm_i915_private *dev_priv, 
u16 reg, u32 value,
return;
}
 }
+
+u32 vlv_flisdsi_read(struct drm_i915_private *dev_priv, u32 reg)
+{
+   u32 val = 0;
+   vlv_sideband_rw(dev_priv, DPIO_DEVFN, IOSF_PORT_FLISDSI,
+   DPIO_OPCODE_REG_READ, reg, &val);
+   return val;
+}
+
+void vlv_flisdsi_write(struct drm_i915_private *dev_priv, u32 reg, u32 val)
+{
+   vlv_sideband_rw(dev_priv, DPIO_DEVFN, IOSF_PORT_FLISDSI,
+   DPIO_OPCODE_REG_WRITE, reg,

[Intel-gfx] [PATCH 4/4] drm/i915: Parameterize the MIPI enabling sequnece and adjust the sequence

2013-10-21 Thread Shobhit Kumar
Has been tested on couple of panels now.

Signed-off-by: Yogesh Mohan Marimuthu 
Signed-off-by: Vijaykumar Balakrishnan 
Signed-off-by: Shobhit Kumar 
---
 drivers/gpu/drm/i915/i915_drv.h  |   11 ++
 drivers/gpu/drm/i915/intel_dsi.c |  334 +-
 2 files changed, 199 insertions(+), 146 deletions(-)

diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h
index 1c42bb4..1c28d02 100644
--- a/drivers/gpu/drm/i915/i915_drv.h
+++ b/drivers/gpu/drm/i915/i915_drv.h
@@ -2375,6 +2375,17 @@ __i915_write(64)
 #define POSTING_READ(reg)  (void)I915_READ_NOTRACE(reg)
 #define POSTING_READ16(reg)(void)I915_READ16_NOTRACE(reg)
 
+#define I915_WRITE_BITS(reg, val, mask) \
+do { \
+   u32 tmp, data; \
+   tmp = I915_READ((reg)); \
+   tmp &= ~(mask); \
+   data = (val) & (mask); \
+   data = data | tmp; \
+   I915_WRITE((reg), data); \
+} while(0)
+
+
 /* "Broadcast RGB" property */
 #define INTEL_BROADCAST_RGB_AUTO 0
 #define INTEL_BROADCAST_RGB_FULL 1
diff --git a/drivers/gpu/drm/i915/intel_dsi.c b/drivers/gpu/drm/i915/intel_dsi.c
index 5a9dbfd..241bb55 100644
--- a/drivers/gpu/drm/i915/intel_dsi.c
+++ b/drivers/gpu/drm/i915/intel_dsi.c
@@ -21,6 +21,8 @@
  * DEALINGS IN THE SOFTWARE.
  *
  * Author: Jani Nikula 
+ *      : Shobhit Kumar 
+ *  : Yogesh Mohan Marimuthu 
  */
 
 #include 
@@ -101,63 +103,80 @@ static void intel_dsi_pre_pll_enable(struct intel_encoder 
*encoder)
vlv_enable_dsi_pll(encoder);
 }
 
-static void intel_dsi_pre_enable(struct intel_encoder *encoder)
-{
-   DRM_DEBUG_KMS("\n");
-}
-
-static void intel_dsi_enable(struct intel_encoder *encoder)
+void intel_dsi_device_ready(struct intel_encoder *encoder)
 {
struct drm_i915_private *dev_priv = encoder->base.dev->dev_private;
struct intel_crtc *intel_crtc = to_intel_crtc(encoder->base.crtc);
struct intel_dsi *intel_dsi = enc_to_intel_dsi(&encoder->base);
int pipe = intel_crtc->pipe;
-   u32 temp;
 
DRM_DEBUG_KMS("\n");
 
if (intel_dsi->dev.dev_ops->panel_reset)
intel_dsi->dev.dev_ops->panel_reset(&intel_dsi->dev);
 
-   temp = I915_READ(MIPI_DEVICE_READY(pipe));
-   if ((temp & DEVICE_READY) == 0) {
-   temp &= ~ULPS_STATE_MASK;
-   I915_WRITE(MIPI_DEVICE_READY(pipe), temp | DEVICE_READY);
-   } else if (temp & ULPS_STATE_MASK) {
-   temp &= ~ULPS_STATE_MASK;
-   I915_WRITE(MIPI_DEVICE_READY(pipe), temp | ULPS_STATE_EXIT);
-   /*
-* We need to ensure that there is a minimum of 1 ms time
-* available before clearing the UPLS exit state.
-*/
-   msleep(2);
-   I915_WRITE(MIPI_DEVICE_READY(pipe), temp);
-   }
+   I915_WRITE_BITS(MIPI_PORT_CTRL(pipe), LP_OUTPUT_HOLD, LP_OUTPUT_HOLD);
+   usleep_range(1000, 1500);
+   I915_WRITE_BITS(MIPI_DEVICE_READY(pipe), DEVICE_READY |
+   ULPS_STATE_EXIT, DEVICE_READY | ULPS_STATE_MASK);
+   usleep_range(2000, 2500);
+   I915_WRITE_BITS(MIPI_DEVICE_READY(pipe), DEVICE_READY,
+   DEVICE_READY | ULPS_STATE_MASK);
+   usleep_range(2000, 2500);
+   I915_WRITE_BITS(MIPI_DEVICE_READY(pipe), 0x00,
+   DEVICE_READY | ULPS_STATE_MASK);
+   usleep_range(2000, 2500);
+   I915_WRITE_BITS(MIPI_DEVICE_READY(pipe), DEVICE_READY,
+   DEVICE_READY | ULPS_STATE_MASK);
+   usleep_range(2000, 2500);
 
if (intel_dsi->dev.dev_ops->send_otp_cmds)
intel_dsi->dev.dev_ops->send_otp_cmds(&intel_dsi->dev);
 
+}
+static void intel_dsi_pre_enable(struct intel_encoder *encoder)
+{
+   DRM_DEBUG_KMS("\n");
+
+   /* put device in ready state */
+   intel_dsi_device_ready(encoder);
+}
+
+static void intel_dsi_enable(struct intel_encoder *encoder)
+{
+   struct drm_device *dev = encoder->base.dev;
+   struct drm_i915_private *dev_priv = dev->dev_private;
+   struct intel_crtc *intel_crtc = to_intel_crtc(encoder->base.crtc);
+   struct intel_dsi *intel_dsi = enc_to_intel_dsi(&encoder->base);
+   int pipe = intel_crtc->pipe;
+   u32 temp;
+
+   DRM_DEBUG_KMS("\n");
+
if (is_cmd_mode(intel_dsi))
I915_WRITE(MIPI_MAX_RETURN_PKT_SIZE(pipe), 8 * 4);
-
-   if (is_vid_mode(intel_dsi)) {
+   else {
msleep(20); /* XXX */
dpi_send_cmd(intel_dsi, TURN_ON);
msleep(100);
 
/* assert ip_tg_enable signal */
temp = I915_READ(MIPI_PORT_CTRL(pipe));
+   temp = temp | intel_dsi->port_bits;
I915_WRITE(MIPI_PORT_CTRL(pipe), temp | DPI_ENABLE);
P

[Intel-gfx] [PATCH 3/4] drm/i915: Compute dsi_clk from pixel clock

2013-10-21 Thread Shobhit Kumar
Minor modification to m_n_p calculations as well

Signed-off-by: Shobhit Kumar 
---
 drivers/gpu/drm/i915/intel_dsi_pll.c |   75 --
 1 file changed, 63 insertions(+), 12 deletions(-)

diff --git a/drivers/gpu/drm/i915/intel_dsi_pll.c 
b/drivers/gpu/drm/i915/intel_dsi_pll.c
index 44279b2..bf12335 100644
--- a/drivers/gpu/drm/i915/intel_dsi_pll.c
+++ b/drivers/gpu/drm/i915/intel_dsi_pll.c
@@ -50,6 +50,8 @@ static const u32 lfsr_converts[] = {
71, 35  /* 91 - 92 */
 };
 
+#ifdef DSI_CLK_FROM_RR
+
 static u32 dsi_rr_formula(const struct drm_display_mode *mode,
  int pixel_format, int video_mode_format,
  int lane_count, bool eotp)
@@ -129,6 +131,40 @@ static u32 dsi_rr_formula(const struct drm_display_mode 
*mode,
return dsi_clk;
 }
 
+#else
+
+/* Get DSI clock from pixel clock */
+static u32 dsi_clk_from_pclk(const struct drm_display_mode *mode,
+ int pixel_format, int lane_count)
+{
+   u32 dsi_bit_clock_hz, dsi_clk;
+   u32 bpp;
+
+   switch (pixel_format) {
+   default:
+   case VID_MODE_FORMAT_RGB888:
+   case VID_MODE_FORMAT_RGB666_LOOSE:
+   bpp = 24;
+   break;
+   case VID_MODE_FORMAT_RGB666:
+   bpp = 18;
+   break;
+   case VID_MODE_FORMAT_RGB565:
+   bpp = 16;
+   break;
+   }
+
+   /* DSI data rate = pixel clock * bits per pixel / lane count
+  pixel clock is converted from KHz to Hz */
+   dsi_bit_clock_hz = (((mode->clock * 1000) * bpp) / lane_count);
+
+   /* DSI clock rate */
+   dsi_clk = dsi_bit_clock_hz / (1000 * 1000);
+   return dsi_clk;
+}
+
+#endif
+
 #ifdef MNP_FROM_TABLE
 
 struct dsi_clock_table {
@@ -208,29 +244,42 @@ static int dsi_calc_mnp(u32 dsi_clk, struct dsi_mnp 
*dsi_mnp)
ref_clk = 25000;
target_dsi_clk = dsi_clk * 1000;
error = 0x;
+   tmp_error = 0x;
calc_m = 0;
calc_p = 0;
 
for (m = 62; m <= 92; m++) {
for (p = 2; p <= 6; p++) {
-
+   /* Find the optimal m and p divisors
+   with minimal error +/- the required clock */
calc_dsi_clk = (m * ref_clk) / p;
-   if (calc_dsi_clk >= target_dsi_clk) {
+   if (calc_dsi_clk == target_dsi_clk) {
+   calc_m = m;
+   calc_p = p;
+   error = 0;
+   break;
+   } else if (calc_dsi_clk > target_dsi_clk)
tmp_error = calc_dsi_clk - target_dsi_clk;
-   if (tmp_error < error) {
-   error = tmp_error;
-   calc_m = m;
-   calc_p = p;
-   }
+   else
+   tmp_error = target_dsi_clk - calc_dsi_clk;
+
+   if (tmp_error < error) {
+   error = tmp_error;
+   calc_m = m;
+   calc_p = p;
}
}
+
+   if (error == 0)
+   break;
}
 
m_seed = lfsr_converts[calc_m - 62];
n = 1;
+
dsi_mnp->dsi_pll_ctrl = 1 << (DSI_PLL_P1_POST_DIV_SHIFT + calc_p - 2);
dsi_mnp->dsi_pll_div = (n - 1) << DSI_PLL_N1_DIV_SHIFT |
-   m_seed << DSI_PLL_M1_DIV_SHIFT;
+   m_seed << DSI_PLL_M1_DIV_SHIFT;
 
return 0;
 }
@@ -249,11 +298,13 @@ static void vlv_configure_dsi_pll(struct intel_encoder 
*encoder)
struct intel_dsi *intel_dsi = enc_to_intel_dsi(&encoder->base);
int ret;
struct dsi_mnp dsi_mnp;
-   u32 dsi_clk;
+   u32 dsi_clk = 0;
 
-   dsi_clk = dsi_rr_formula(mode, intel_dsi->pixel_format,
-intel_dsi->video_mode_format,
-intel_dsi->lane_count, 
!intel_dsi->eot_disable);
+   if (intel_dsi->dsi_clock_freq)
+   dsi_clk = intel_dsi->dsi_clock_freq;
+   else
+   dsi_clk = dsi_clk_from_pclk(mode, intel_dsi->pixel_format,
+   intel_dsi->lane_count);
 
ret = dsi_calc_mnp(dsi_clk, &dsi_mnp);
if (ret) {
-- 
1.7.9.5

___
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/intel-gfx


Re: [Intel-gfx] [PATCH 4/4] drm/i915: Parameterize the MIPI enabling sequnece and adjust the sequence

2013-10-22 Thread Shobhit Kumar

On 10/21/2013 6:53 PM, Ville Syrjälä wrote:

On Mon, Oct 21, 2013 at 05:51:07PM +0530, Shobhit Kumar wrote:

Has been tested on couple of panels now.


While it's nice to get patches, I can't say I'm very happy about the
shape of this one.

The patch contains several changes in one patch. It should be split up
into several patches. Based on a cursory examination I would suggest
something like this:
- weird ULPS ping-pong


Suggested and approved sequence by HW team for ULPS entry/exit is as 
follows during enable time -

set DEVICE_READY --> Clear DEVICE_READY --> set DEVICE_READY

And during disable time to flush all FIFOs -
set ENTER_SLEEP --> EXIT_SLEEP --> ENTER_SLEEP

I will push this is new patch


- add backlight support


Ok will push in new patch


- moving the ->disable() call


Earlier disable was called at the beginning even before pixel stream was 
stopped. Ideal flow would be to disable pixel stream and then follow 
panel's required disable sequence



- each of the new intel_dsi->foo/bar/etc. parameter could probably
   be a separate patch


Ok, I can break all parameter changes into a separate patch



As far as the various timeout related parameters are concerned, to me
it would make more sense to specify them in usecs or some other real
world unit. Or you could provide/leave in some helper functions to
calculate the clock based values from some real world values.


Few timeouts are as per spec. Are you referring to back-light or 
shutdown packet delays ? If yes we can change them to usecs.




And finally justficiation for each of these changes is missing from
the current patch. We want to know why the code has to change.


I hope I have provided some clarifications above. I will work on 
splitting this patch into few more patches for more clarity.


Regards
Shobhit





Signed-off-by: Yogesh Mohan Marimuthu 
Signed-off-by: Vijaykumar Balakrishnan 
Signed-off-by: Shobhit Kumar 
---
  drivers/gpu/drm/i915/i915_drv.h  |   11 ++
  drivers/gpu/drm/i915/intel_dsi.c |  334 +-
  2 files changed, 199 insertions(+), 146 deletions(-)

diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h
index 1c42bb4..1c28d02 100644
--- a/drivers/gpu/drm/i915/i915_drv.h
+++ b/drivers/gpu/drm/i915/i915_drv.h
@@ -2375,6 +2375,17 @@ __i915_write(64)
  #define POSTING_READ(reg) (void)I915_READ_NOTRACE(reg)
  #define POSTING_READ16(reg)   (void)I915_READ16_NOTRACE(reg)

+#define I915_WRITE_BITS(reg, val, mask) \
+do { \
+   u32 tmp, data; \
+   tmp = I915_READ((reg)); \
+   tmp &= ~(mask); \
+   data = (val) & (mask); \
+   data = data | tmp; \
+   I915_WRITE((reg), data); \
+} while(0)
+
+
  /* "Broadcast RGB" property */
  #define INTEL_BROADCAST_RGB_AUTO 0
  #define INTEL_BROADCAST_RGB_FULL 1
diff --git a/drivers/gpu/drm/i915/intel_dsi.c b/drivers/gpu/drm/i915/intel_dsi.c
index 5a9dbfd..241bb55 100644
--- a/drivers/gpu/drm/i915/intel_dsi.c
+++ b/drivers/gpu/drm/i915/intel_dsi.c
@@ -21,6 +21,8 @@
   * DEALINGS IN THE SOFTWARE.
   *
   * Author: Jani Nikula 
+ *  : Shobhit Kumar 
+ *  : Yogesh Mohan Marimuthu 
   */

  #include 
@@ -101,63 +103,80 @@ static void intel_dsi_pre_pll_enable(struct intel_encoder 
*encoder)
vlv_enable_dsi_pll(encoder);
  }

-static void intel_dsi_pre_enable(struct intel_encoder *encoder)
-{
-   DRM_DEBUG_KMS("\n");
-}
-
-static void intel_dsi_enable(struct intel_encoder *encoder)
+void intel_dsi_device_ready(struct intel_encoder *encoder)
  {
struct drm_i915_private *dev_priv = encoder->base.dev->dev_private;
struct intel_crtc *intel_crtc = to_intel_crtc(encoder->base.crtc);
struct intel_dsi *intel_dsi = enc_to_intel_dsi(&encoder->base);
int pipe = intel_crtc->pipe;
-   u32 temp;

DRM_DEBUG_KMS("\n");

if (intel_dsi->dev.dev_ops->panel_reset)
intel_dsi->dev.dev_ops->panel_reset(&intel_dsi->dev);

-   temp = I915_READ(MIPI_DEVICE_READY(pipe));
-   if ((temp & DEVICE_READY) == 0) {
-   temp &= ~ULPS_STATE_MASK;
-   I915_WRITE(MIPI_DEVICE_READY(pipe), temp | DEVICE_READY);
-   } else if (temp & ULPS_STATE_MASK) {
-   temp &= ~ULPS_STATE_MASK;
-   I915_WRITE(MIPI_DEVICE_READY(pipe), temp | ULPS_STATE_EXIT);
-   /*
-* We need to ensure that there is a minimum of 1 ms time
-* available before clearing the UPLS exit state.
-*/
-   msleep(2);
-   I915_WRITE(MIPI_DEVICE_READY(pipe), temp);
-   }
+   I915_WRITE_BITS(MIPI_PORT_CTRL(pipe), LP_OUTPUT_HOLD, LP_OUTPUT_HOLD);
+   usleep_range(1000, 1500);
+   I915_WRITE_BITS(MIPI_DEVICE_READY(pipe), DEVICE_READY |
+   ULPS_STATE_EXIT, DEVICE_READY | ULPS_STATE_MASK);
+  

  1   2   3   >