drm/i915: ValleyView mode setting limits and PLL functions
Subsystems (3)
PATCH 1/14 drm/i915: ValleyView mode setting limits and PLL functions
Add some VLV limit structures and update the PLL code.
v2: resolve conflicts, Vijay to re-post with PLL valid checks and fixed limits
v3: re-add dpio write function
v4: squash in Vijay's fixes for the PLL limits and clean up the m/n finder
--- drivers/gpu/drm/i915/i915_reg.h | 1 + drivers/gpu/drm/i915/intel_display.c | 240 +++++++++++++++++++++++++++++++++- 2 files changed, 239 insertions(+), 2 deletions(-)
drivers/gpu/drm/i915/i915_reg.h +1 -0
@@ -900,6 +900,7 @@#define DPLL_P2_CLOCK_DIV_MASK 0x03000000/* i915 */ #define DPLL_FPA01_P1_POST_DIV_MASK 0x00ff0000/* i915 */ #define DPLL_FPA01_P1_POST_DIV_MASK_PINEVIEW 0x00ff8000/* Pineview */ +#define DPLL_LOCK_VLV (1<<15)#define DPLL_INTEGRATED_CLOCK_VLV (1<<13)#define SRX_INDEX 0x3c4
drivers/gpu/drm/i915/intel_display.c +238 -2
300 lines not on this page · raw message
Signature · 1 line
1.7.9.5
PATCH 2/14 drm/i915: Enable DP panel power sequencing for ValleyView
From: Shobhit Kumar <[email protected]>
VLV supports two dp panels, there are two set of panel power sequence registers which needed to be programmed based on the configured pipe. This patch add supports for the same
--- drivers/gpu/drm/i915/i915_reg.h | 12 ++++++++++++ drivers/gpu/drm/i915/intel_dp.c | 8 +++++++- 2 files changed, 19 insertions(+), 1 deletion(-)
drivers/gpu/drm/i915/i915_reg.h +12 -0
@@ -3854,6 +3854,18 @@#define BLC_PWM_PCH_CTL2 0xc8254 +#define PIPEA_PP_STATUS 0x61200 +#define PIPEA_PP_CONTROL 0x61204 +#define PIPEA_PP_ON_DELAYS 0x61208 +#define PIPEA_PP_OFF_DELAYS 0x6120c +#define PIPEA_PP_DIVISOR 0x61210 + +#define PIPEB_PP_STATUS 0x61300 +#define PIPEB_PP_CONTROL 0x61304 +#define PIPEB_PP_ON_DELAYS 0x61308 +#define PIPEB_PP_OFF_DELAYS 0x6130c +#define PIPEB_PP_DIVISOR 0x61310 +#define PCH_PP_STATUS 0xc7200#define PCH_PP_CONTROL 0xc7204#define PANEL_UNLOCK_REGS (0xabcd << 16)
drivers/gpu/drm/i915/intel_dp.c +7 -1
@@ -342,7 +342,13 @@ static bool ironlake_edp_have_panel_power(struct intel_dp *intel_dp)struct drm_device *dev = intel_dp->base.base.dev;struct drm_i915_private *dev_priv = dev->dev_private; -return (I915_READ (PCH_PP_STATUS ) &PP_ON ) !=0 ; +if (IS_VALLEYVIEW (dev)) { +if (I915_READ (intel_dp->output_reg) &DP_PIPEB_SELECT ) +return (I915_READ (PIPEB_PP_STATUS ) &PP_ON ) !=0 ; +else +return (I915_READ (PIPEA_PP_STATUS ) &PP_ON ) !=0 ; + }else +return (I915_READ (PCH_PP_STATUS ) &PP_ON ) !=0 ; }static bool ironlake_edp_have_panel_vdd (struct intel_dp *intel_dp)
Signature · 1 line
1.7.9.5
Re: [PATCH 02/14] drm/i915: Enable DP panel power sequencing for ValleyView
Quoted 11 lines · Jesse Barnes
From: Shobhit Kumar <[email protected]>
VLV supports two dp panels, there are two set of panel power sequence registers which needed to be programmed based on the configured pipe. This patch add supports for the same
Signed-off-by Beeresh G <[email protected]>Reviewed-by Vijay Purushothaman <[email protected]>Reviewed-by Jesse Barnes <[email protected]>Signed-off-by Jesse Barnes <[email protected]>
I've dropped the code change below - this clearly needs a more complete solution. Also, I still fail at getting access to vlv docs :( -Daniel
Quoted 54 lines
--- drivers/gpu/drm/i915/i915_reg.h | 12 ++++++++++++ drivers/gpu/drm/i915/intel_dp.c | 8 +++++++- 2 files changed, 19 insertions(+), 1 deletion(-)drivers/gpu/drm/i915/i915_reg.h +12
-0@@ -3854,6 +3854,18 @@#define BLC_PWM_PCH_CTL2 0xc8254 +#define PIPEA_PP_STATUS 0x61200 +#define PIPEA_PP_CONTROL 0x61204 +#define PIPEA_PP_ON_DELAYS 0x61208 +#define PIPEA_PP_OFF_DELAYS 0x6120c +#define PIPEA_PP_DIVISOR 0x61210 + +#define PIPEB_PP_STATUS 0x61300 +#define PIPEB_PP_CONTROL 0x61304 +#define PIPEB_PP_ON_DELAYS 0x61308 +#define PIPEB_PP_OFF_DELAYS 0x6130c +#define PIPEB_PP_DIVISOR 0x61310 +#define PCH_PP_STATUS 0xc7200#define PCH_PP_CONTROL 0xc7204#define PANEL_UNLOCK_REGS (0xabcd << 16)drivers/gpu/drm/i915/intel_dp.c +7
-1@@ -342,7 +342,13 @@ static bool ironlake_edp_have_panel_power(struct intel_dp *intel_dp)struct drm_device *dev = intel_dp->base.base.dev;struct drm_i915_private *dev_priv = dev->dev_private; -return (I915_READ (PCH_PP_STATUS ) &PP_ON ) !=0 ; +if (IS_VALLEYVIEW (dev)) { +if (I915_READ (intel_dp->output_reg) &DP_PIPEB_SELECT ) +return (I915_READ (PIPEB_PP_STATUS ) &PP_ON ) !=0 ; +else +return (I915_READ (PIPEA_PP_STATUS ) &PP_ON ) !=0 ; + }else +return (I915_READ (PCH_PP_STATUS ) &PP_ON ) !=0 ; }static bool ironlake_edp_have_panel_vdd (struct intel_dp *intel_dp)Signature · 6 lines
1.7.9.5 _______________________________________________ Intel-gfx mailing list [email protected] http://lists.freedesktop.org/mailman/listinfo/intel-gfx
Signature · 3 lines
Daniel Vetter Mail: [email protected] Mobile: +41 (0)79 365 57 48
Re: [PATCH 02/14] drm/i915: Enable DP panel power sequencing for ValleyView
Quoted 7 lines · On Wed, 20 Jun 2012 14:50:51 +0200 Daniel Vetter <[email protected]> wrote:
Quoted 6 lines · Jesse Barnes
From: Shobhit Kumar <[email protected]>
VLV supports two dp panels, there are two set of panel power sequence registers which needed to be programmed based on the configured pipe. This patch add supports for the same
Quoted 8 lines
Quoted 5 lines
Signed-off-by Beeresh G <[email protected]>Reviewed-by Vijay Purushothaman <[email protected]>Reviewed-by Jesse Barnes <[email protected]>Signed-off-by Jesse Barnes <[email protected]>I've dropped the code change below - this clearly needs a more complete solution. Also, I still fail at getting access to vlv docs :(
Yeah sounds good. I actually dropped it too in a local rebase.
Signature · 1 line
Jesse Barnes, Intel Open Source Technology Center
PATCH 3/14 drm/i915: add ValleyView specific CRT detect function
In reply to Jesse BarnesMight be able to merge this back in at some point, but we're seeing bugs with ADPA based detection, so keep it separate for now with explicit hotplug trigger usage.
v2: drop superfluous debug message
v3: comment forced detection, need to debug (Eugeni)
--- drivers/gpu/drm/i915/intel_crt.c | 39 ++++++++++++++++++++++++++++++++++++++ 1 file changed, 39 insertions(+)
drivers/gpu/drm/i915/intel_crt.c +39 -0
@@ -230,6 +230,42 @@ static bool intel_ironlake_crt_detect_hotplug(struct drm_connector *connector)return ret; } +static bool valleyview_crt_detect_hotplug (struct drm_connector *connector) +{ +struct drm_device *dev = connector->dev; +struct drm_i915_private *dev_priv = dev->dev_private; +u32 adpa; +bool ret; +u32 save_adpa; + + save_adpa = adpa =I915_READ (ADPA ); +DRM_DEBUG_KMS ("trigger hotplug detect cycle: adpa=0x%x\n" , adpa); + + adpa |=ADPA_CRT_HOTPLUG_FORCE_TRIGGER ; + +I915_WRITE (ADPA , adpa); + +if (wait_for ((I915_READ (ADPA ) &ADPA_CRT_HOTPLUG_FORCE_TRIGGER ) ==0 , +1000 )) { +DRM_DEBUG_KMS ("timed out waiting for FORCE_TRIGGER" ); +I915_WRITE (ADPA , save_adpa); + } + +/* Check the status to see if both blue and green are on now */ + adpa =I915_READ (ADPA ); +if ((adpa &ADPA_CRT_HOTPLUG_MONITOR_MASK ) !=0 ) + ret = true; +else + ret = false; + +DRM_DEBUG_KMS ("valleyview hotplug adpa=0x%x, result %d\n" , adpa, ret); + +/* FIXME: debug force function and remove */ + ret = true; + +return ret; +} +/** * Uses CRT_HOTPLUG_EN and CRT_HOTPLUG_STAT to detect CRT presence. *
@@ -249,6 +285,9 @@ static bool intel_crt_detect_hotplug(struct drm_connector *connector)if (HAS_PCH_SPLIT (dev))return intel_ironlake_crt_detect_hotplug (connector); +if (IS_VALLEYVIEW (dev)) +return valleyview_crt_detect_hotplug (connector); +/* * On 4 series desktop, CRT detect sequence need to be done twice * to get a reliable result.
Signature · 1 line
1.7.9.5
PATCH 4/14 drm/i915: add HDMI and DP port enumeration on ValleyView
In reply to Jesse BarnesValleyView is similar to IbexPeak here, but with different register offsets.
v2: use SDVOB instead ov VLV_HDMIB (Daniel)
drop unnecessary eDP check in DP_C init (Daniel)
eDP support will be coming later from Shobit.
--- drivers/gpu/drm/i915/i915_reg.h | 1 - drivers/gpu/drm/i915/intel_display.c | 17 +++++++++++++++++ 2 files changed, 17 insertions(+), 1 deletion(-)
drivers/gpu/drm/i915/i915_reg.h +0 -1
@@ -3808,7 +3808,6 @@#define ADPA_CRT_HOTPLUG_FORCE_TRIGGER (1<<16)/* or SDVOB */ -#define VLV_HDMIB 0x61140#define HDMIB 0xe1140#define PORT_ENABLE (1 << 31)#define TRANSCODER (pipe) ((pipe) << 30)
drivers/gpu/drm/i915/intel_display.c +17 -0
@@ -6762,7 +6762,24 @@ static void intel_setup_outputs(struct drm_device *dev)if (!dpd_is_edp && (I915_READ (PCH_DP_D ) &DP_DETECTED ))intel_dp_init (dev,PCH_DP_D ); + }else if (IS_VALLEYVIEW (dev)) { +int found; + +if (I915_READ (SDVOB ) &PORT_DETECTED ) { +/* SDVOB multiplex with HDMIB */ + found =intel_sdvo_init (dev,SDVOB , true); +if (!found) +intel_hdmi_init (dev,SDVOB ); +if (!found && (I915_READ (DP_B ) &DP_DETECTED )) +intel_dp_init (dev,DP_B ); + } + +if (I915_READ (SDVOC ) &PORT_DETECTED ) +intel_hdmi_init (dev,SDVOC ); +/* Shares lanes with HDMI on SDVOC */ +if (I915_READ (DP_C ) &DP_DETECTED ) +intel_dp_init (dev,DP_C ); }else if (SUPPORTS_DIGITAL_OUTPUTS (dev)) {bool found = false;
Signature · 1 line
1.7.9.5
PATCH 5/14 drm/i915: access VLV regs through read/write switch
In reply to Jesse BarnesSince the offsets have all moved around.
v2: switch IS_DISPLAYREG and IS_VALLEYVIEW checks around since the latter is
cheaper (Daniel)
bail out early in IS_DISPLAYREG if the reg is in the new range (Daniel)
--- drivers/gpu/drm/i915/i915_drv.c | 87 ++++++++++++++++++++++++++++++++++++++- 1 file changed, 85 insertions(+), 2 deletions(-)
drivers/gpu/drm/i915/i915_drv.c +85 -2
@@ -1144,6 +1144,84 @@ MODULE_LICENSE("GPL and additional rights"); ((reg) != FORCEWAKE)) && \ (!IS_VALLEYVIEW((dev_priv)->dev)) +static bool IS_DISPLAYREG (u32 reg) +{ +/* +* This should make it easier to transition modules over to the +* new register block scheme, since we can do it incrementally. +*/ +if (reg >=0x180000 ) +return false; + +if (reg >=RENDER_RING_BASE && + reg <RENDER_RING_BASE +0xff ) +return false; +if (reg >=GEN6_BSD_RING_BASE && + reg <GEN6_BSD_RING_BASE +0xff ) +return false; +if (reg >=BLT_RING_BASE && + reg <BLT_RING_BASE +0xff ) +return false; + +if (reg ==PGTBL_ER ) +return false; + +if (reg >=IPEIR_I965 && + reg <HWSTAM ) +return false; + +if (reg ==MI_MODE ) +return false; + +if (reg ==GFX_MODE_GEN7 ) +return false; + +if (reg ==RENDER_HWS_PGA_GEN7 || + reg ==BSD_HWS_PGA_GEN7 || + reg ==BLT_HWS_PGA_GEN7 ) +return false; + +if (reg ==GEN6_BSD_SLEEP_PSMI_CONTROL || + reg ==GEN6_BSD_RNCID ) +return false; + +if (reg ==GEN6_BLITTER_ECOSKPD ) +return false; + +if (reg >=0x4000c && + reg <=0x4002c ) +return false; + +if (reg >=0x4f000 && + reg <=0x4f08f ) +return false; + +if (reg >=0x4f100 && + reg <=0x4f11f ) +return false; + +if (reg >=VLV_MASTER_IER && + reg <=GEN6_PMIER ) +return false; + +if (reg >=FENCE_REG_SANDYBRIDGE_0 && + reg < (FENCE_REG_SANDYBRIDGE_0 + (16 *8 ))) +return false; + +if (reg >=VLV_IIR_RW && + reg <=VLV_ISR ) +return false; + +if (reg ==FORCEWAKE_VLV || + reg ==FORCEWAKE_ACK_VLV ) +return false; + +if (reg ==GEN6_GDRST ) +return false; + +return true; +} +#define __i915_read (x, y) \ u##x i915_read##x(struct drm_i915_private *dev_priv, u32 reg) { \ u##x val = 0; \
@@ -1156,6 +1234,8 @@ u##x i915_read##x(struct drm_i915_private *dev_priv, u32 reg) { \if (dev_priv->forcewake_count ==0 ) \ dev_priv->display.force_wake_put (dev_priv); \spin_unlock_irqrestore (&dev_priv->gt_lock, irqflags); \ + }else if (IS_VALLEYVIEW (dev_priv->dev) &&IS_DISPLAYREG (reg)) { \ + val = read##y(dev_priv->regs + reg + 0x180000); \ } else { \ val = read##y(dev_priv->regs + reg); \ } \
@@ -1175,8 +1255,11 @@ void i915_write##x(struct drm_i915_private *dev_priv, u32 reg, u##x val) { \trace_i915_reg_rw (true, reg, val,sizeof (val)); \if (NEEDS_FORCE_WAKE ((dev_priv), (reg))) { \ __fifo_ret =__gen6_gt_wait_for_fifo (dev_priv); \ - } \ - write##y(val, dev_priv->regs + reg); \ + }else if (IS_VALLEYVIEW (dev_priv->dev) &&IS_DISPLAYREG (reg)) { \ + write##y(val, dev_priv->regs + reg + 0x180000); \ + } else { \ + write##y(val, dev_priv->regs + reg); \ + } \ if (unlikely(__fifo_ret)) { \ gen6_gt_check_fifodbg(dev_priv); \ } \
Signature · 1 line
1.7.9.5
PATCH 6/14 drm/i915: VLV VGA port only handles on & off, like PCH VGA
In reply to Jesse Barnes--- drivers/gpu/drm/i915/intel_crt.c | 3 +++ 1 file changed, 3 insertions(+)
drivers/gpu/drm/i915/intel_crt.c +3 -0
@@ -88,6 +88,9 @@ static void gmch_crt_dpms(struct drm_encoder *encoder, int mode) temp &= ~(ADPA_HSYNC_CNTL_DISABLE |ADPA_VSYNC_CNTL_DISABLE ); temp &= ~ADPA_DAC_ENABLE ; +if (IS_VALLEYVIEW (dev) && mode !=DRM_MODE_DPMS_ON ) + mode =DRM_MODE_DPMS_OFF ; +switch (mode) {case DRM_MODE_DPMS_ON : temp |=ADPA_DAC_ENABLE ;
Signature · 1 line
1.7.9.5
PATCH 7/14 agp/intel: allow cacheable and GDFT PTEs on ValleyView
In reply to Jesse BarnesThe PTE format is similar to SNB, but we don't support an MLC and don't need chipset flushing.
--- drivers/char/agp/intel-gtt.c | 11 +++++++++-- 1 file changed, 9 insertions(+), 2 deletions(-)
drivers/char/agp/intel-gtt.c +9 -2
@@ -1182,9 +1182,17 @@ static void gen6_write_entry(dma_addr_t addr, unsigned int entry,static void valleyview_write_entry (dma_addr_t addr,unsigned int entry,unsigned int flags) { +unsigned int type_mask = flags & ~AGP_USER_CACHED_MEMORY_GFDT ; +unsigned int gfdt = flags &AGP_USER_CACHED_MEMORY_GFDT ;u32 pte_flags; - pte_flags =GEN6_PTE_UNCACHED |I810_PTE_VALID ; +if (type_mask ==AGP_USER_MEMORY ) + pte_flags =GEN6_PTE_UNCACHED |I810_PTE_VALID ; +else { + pte_flags =GEN6_PTE_LLC |I810_PTE_VALID ; +if (gfdt) + pte_flags |=GEN6_PTE_GFDT ; + }/* gen6 has bit11-4 for physical addr bit39-32 */ addr |= (addr >>28 ) &0xff0 ;
@@ -1379,7 +1387,6 @@ static const struct intel_gtt_driver valleyview_gtt_driver = { .write_entry = valleyview_write_entry, .dma_mask_size = 40, .check_flags = gen6_check_flags, - .chipset_flush = i9xx_chipset_flush, };/* Table to describe Intel GMCH and AGP/PCIE GART drivers. At least one of
Signature · 1 line
1.7.9.5
Re: [PATCH 07/14] agp/intel: allow cacheable and GDFT PTEs on ValleyView
Quoted 4 lines · Jesse Barnes
The PTE format is similar to SNB, but we don't support an MLC and don't need chipset flushing.
Signed-off-by Jesse Barnes <[email protected]>
I have my questions whether this is right, given that MLC died for snb & ivb, that ivb has grown a L3$ cache instead (which vlv seems to have, too) and that the LLC bit here isn't actually LLC, but just means 'snoop cpu caches'.
But I plan to burn this all with the heat of a thousands suns in my gtt rework, so who cares ;-)
-Daniel
Quoted 42 lines
--- drivers/char/agp/intel-gtt.c | 11 +++++++++-- 1 file changed, 9 insertions(+), 2 deletions(-)drivers/char/agp/intel-gtt.c +9
-2@@ -1182,9 +1182,17 @@ static void gen6_write_entry(dma_addr_t addr, unsigned int entry,static void valleyview_write_entry (dma_addr_t addr,unsigned int entry,unsigned int flags) { +unsigned int type_mask = flags & ~AGP_USER_CACHED_MEMORY_GFDT ; +unsigned int gfdt = flags &AGP_USER_CACHED_MEMORY_GFDT ;u32 pte_flags; - pte_flags =GEN6_PTE_UNCACHED |I810_PTE_VALID ; +if (type_mask ==AGP_USER_MEMORY ) + pte_flags =GEN6_PTE_UNCACHED |I810_PTE_VALID ; +else { + pte_flags =GEN6_PTE_LLC |I810_PTE_VALID ; +if (gfdt) + pte_flags |=GEN6_PTE_GFDT ; + }/* gen6 has bit11-4 for physical addr bit39-32 */ addr |= (addr >>28 ) &0xff0 ;@@ -1379,7 +1387,6 @@ static const struct intel_gtt_driver valleyview_gtt_driver = { .write_entry = valleyview_write_entry, .dma_mask_size = 40, .check_flags = gen6_check_flags, - .chipset_flush = i9xx_chipset_flush, };/* Table to describe Intel GMCH and AGP/PCIE GART drivers. At least one of Signature · 6 lines
1.7.9.5 _______________________________________________ Intel-gfx mailing list [email protected] http://lists.freedesktop.org/mailman/listinfo/intel-gfx
Signature · 3 lines
Daniel Vetter Mail: [email protected] Mobile: +41 (0)79 365 57 48
Re: [PATCH 07/14] agp/intel: allow cacheable and GDFT PTEs on ValleyView
Quoted 10 lines · On Wed, 20 Jun 2012 14:57:17 +0200 Daniel Vetter <[email protected]> wrote:
Quoted 4 lines · Jesse Barnes
The PTE format is similar to SNB, but we don't support an MLC and don't need chipset flushing.
Signed-off-by Jesse Barnes <[email protected]>I have my questions whether this is right, given that MLC died for snb & ivb, that ivb has grown a L3$ cache instead (which vlv seems to have, too) and that the LLC bit here isn't actually LLC, but just means 'snoop cpu caches'.
Yeah I dropped the MLC part and didn't rename the LLC bit which might be a little confusing, but afaict from the VLV docs this is correct and actually works here (i.e. my last "cacheability is different" patch is unneeded).
Signature · 1 line
Jesse Barnes, Intel Open Source Technology Center
PATCH 8/14 drm/i915: support page flipping on ValleyView
In reply to Jesse BarnesAnd restructure the IRQ handling a little. We can use pipestat for most things, and make sure we don't affect pipe events when enabling and disabling vblank interupts.
--- drivers/gpu/drm/i915/i915_irq.c | 62 +++++++++++++++++---------------------- 1 file changed, 27 insertions(+), 35 deletions(-)
drivers/gpu/drm/i915/i915_irq.c +27 -35
@@ -513,15 +513,10 @@ static irqreturn_t valleyview_irq_handler(DRM_IRQ_ARGS)unsigned long irqflags;int pipe;u32 pipe_stats[I915_MAX_PIPES ]; -u32 vblank_status; -int vblank =0 ;bool blc_event;atomic_inc (&dev_priv->irq_received); - vblank_status =PIPE_START_VBLANK_INTERRUPT_STATUS | -PIPE_VBLANK_INTERRUPT_STATUS ; -while (true) { iir =I915_READ (VLV_IIR ); gt_iir =I915_READ (GTIIR );
@@ -551,6 +546,16 @@ static irqreturn_t valleyview_irq_handler(DRM_IRQ_ARGS) }spin_unlock_irqrestore (&dev_priv->irq_lock, irqflags); +for_each_pipe (pipe) { +if (pipe_stats[pipe] &PIPE_VBLANK_INTERRUPT_STATUS ) +drm_handle_vblank (dev, pipe); + +if (pipe_stats[pipe] &PLANE_FLIPDONE_INT_STATUS_VLV ) { +intel_prepare_page_flip (dev, pipe); +intel_finish_page_flip (dev, pipe); + } + } +/* Consume port. Then clear IIR or we'll miss events */ if (iir &I915_DISPLAY_PORT_INTERRUPT ) {u32 hotplug_status =I915_READ (PORT_HOTPLUG_STAT );
@@ -565,19 +570,6 @@ static irqreturn_t valleyview_irq_handler(DRM_IRQ_ARGS)I915_READ (PORT_HOTPLUG_STAT ); } - -if (iir &I915_DISPLAY_PIPE_A_VBLANK_INTERRUPT ) { -drm_handle_vblank (dev,0 ); - vblank++; -intel_finish_page_flip (dev,0 ); - } - -if (iir &I915_DISPLAY_PIPE_B_VBLANK_INTERRUPT ) { -drm_handle_vblank (dev,1 ); - vblank++; -intel_finish_page_flip (dev,0 ); - } -if (pipe_stats[pipe] &PIPE_LEGACY_BLC_EVENT_STATUS ) blc_event = true;
@@ -1478,23 +1470,20 @@ static int valleyview_enable_vblank(struct drm_device *dev, int pipe) {drm_i915_private_t *dev_priv = (drm_i915_private_t *) dev->dev_private;unsigned long irqflags; -u32 dpfl, imr; +u32 imr;if (!i915_pipe_enabled (dev, pipe))return -EINVAL ;spin_lock_irqsave (&dev_priv->irq_lock, irqflags); - dpfl =I915_READ (VLV_DPFLIPSTAT ); imr =I915_READ (VLV_IMR ); -if (pipe ==0 ) { - dpfl |=PIPEA_VBLANK_INT_EN ; +if (pipe ==0 ) imr &= ~I915_DISPLAY_PIPE_A_VBLANK_INTERRUPT ; - }else { - dpfl |=PIPEA_VBLANK_INT_EN ; +else imr &= ~I915_DISPLAY_PIPE_B_VBLANK_INTERRUPT ; - } -I915_WRITE (VLV_DPFLIPSTAT , dpfl);I915_WRITE (VLV_IMR , imr); +i915_enable_pipestat (dev_priv, pipe, +PIPE_START_VBLANK_INTERRUPT_ENABLE );spin_unlock_irqrestore (&dev_priv->irq_lock, irqflags);return 0 ;
@@ -1544,20 +1533,17 @@ static void valleyview_disable_vblank(struct drm_device *dev, int pipe) {drm_i915_private_t *dev_priv = (drm_i915_private_t *) dev->dev_private;unsigned long irqflags; -u32 dpfl, imr; +u32 imr;spin_lock_irqsave (&dev_priv->irq_lock, irqflags); - dpfl =I915_READ (VLV_DPFLIPSTAT ); +i915_disable_pipestat (dev_priv, pipe, +PIPE_START_VBLANK_INTERRUPT_ENABLE ); imr =I915_READ (VLV_IMR ); -if (pipe ==0 ) { - dpfl &= ~PIPEA_VBLANK_INT_EN ; +if (pipe ==0 ) imr |=I915_DISPLAY_PIPE_A_VBLANK_INTERRUPT ; - }else { - dpfl &= ~PIPEB_VBLANK_INT_EN ; +else imr |=I915_DISPLAY_PIPE_B_VBLANK_INTERRUPT ; - }I915_WRITE (VLV_IMR , imr); -I915_WRITE (VLV_DPFLIPSTAT , dpfl);spin_unlock_irqrestore (&dev_priv->irq_lock, irqflags); }
@@ -1894,10 +1880,13 @@ static int valleyview_irq_postinstall(struct drm_device *dev)u32 render_irqs;u32 enable_mask;u32 hotplug_en =I915_READ (PORT_HOTPLUG_EN ); +u32 pipestat_enable =PLANE_FLIP_DONE_INT_EN_VLV ;u16 msid; enable_mask =I915_DISPLAY_PORT_INTERRUPT ; - enable_mask |=I915_DISPLAY_PIPE_A_VBLANK_INTERRUPT | + enable_mask |=I915_DISPLAY_PIPE_A_EVENT_INTERRUPT | +I915_DISPLAY_PIPE_A_VBLANK_INTERRUPT | +I915_DISPLAY_PIPE_B_EVENT_INTERRUPT |I915_DISPLAY_PIPE_B_VBLANK_INTERRUPT ; dev_priv->irq_mask = ~enable_mask;
@@ -1919,6 +1908,9 @@ static int valleyview_irq_postinstall(struct drm_device *dev)I915_WRITE (PIPESTAT (1 ),0xffff );POSTING_READ (VLV_IER ); +i915_enable_pipestat (dev_priv,0 , pipestat_enable); +i915_enable_pipestat (dev_priv,1 , pipestat_enable); +I915_WRITE (VLV_IIR ,0xffffffff );I915_WRITE (VLV_IIR ,0xffffffff );
Signature · 1 line
1.7.9.5
PATCH 9/14 drm/i915: enable display messages to GT on ValleyView
In reply to Jesse Barnes--- drivers/gpu/drm/i915/intel_pm.c | 7 +++++++ 1 file changed, 7 insertions(+)
drivers/gpu/drm/i915/intel_pm.c +7 -0
@@ -3474,6 +3474,13 @@ static void valleyview_init_clock_gating(struct drm_device *dev)I915_WRITE (CACHE_MODE_1 ,_MASKED_BIT_ENABLE (PIXEL_SUBSPAN_COLLECT_OPT_DISABLE )); + +/* +* On ValleyView, the GUnit needs to signal the GT +* when flip and other events complete. So enable +* all the GUnit->GT interrupts here +*/ +I915_WRITE (VLV_DPFLIPSTAT ,0x3f7f0000 ); }static void g4x_init_clock_gating (struct drm_device *dev)
Signature · 1 line
1.7.9.5
Re: [PATCH 09/14] drm/i915: enable display messages to GT on ValleyView
Quoted 10 lines · Jesse Barnes
Signed-off-by Jesse Barnes <[email protected]>--- drivers/gpu/drm/i915/intel_pm.c | 7 +++++++ 1 file changed, 7 insertions(+)drivers/gpu/drm/i915/intel_pm.c +0
-0
drivers/gpu/drm/i915/intel_pm.c static void valleyview_init_clock_gating(struct drm_device *dev) · line 3483
Quoted 10 lines
drivers/gpu/drm/i915/intel_pm.c +7
-0@@ -3474,6 +3474,13 @@ static void valleyview_init_clock_gating(struct drm_device *dev)I915_WRITE (CACHE_MODE_1 ,_MASKED_BIT_ENABLE (PIXEL_SUBSPAN_COLLECT_OPT_DISABLE )); + +/* +* On ValleyView, the GUnit needs to signal the GT +* when flip and other events complete. So enable +* all the GUnit->GT interrupts here +*/ +I915_WRITE (VLV_DPFLIPSTAT ,0x3f7f0000 );
... can we have less magic here, please? Not that anyone but you seems to have access to docs :(
-Daniel
Quoted 10 lines
drivers/gpu/drm/i915/intel_pm.c +0
-0}static void g4x_init_clock_gating (struct drm_device *dev)Signature · 6 lines
1.7.9.5 _______________________________________________ Intel-gfx mailing list [email protected] http://lists.freedesktop.org/mailman/listinfo/intel-gfx
Signature · 3 lines
Daniel Vetter Mail: [email protected] Mobile: +41 (0)79 365 57 48
PATCH 10/14 agp/intel: use correct GTT offset on VLV
In reply to Jesse BarnesVLV is a gen7 device, but we don't currently handle that in the switch. So add it and write the PTEs correctly.
--- drivers/char/agp/intel-gtt.c | 1 + 1 file changed, 1 insertion(+)
drivers/char/agp/intel-gtt.c +1 -0
@@ -1252,6 +1252,7 @@ static int i9xx_setup(void)switch (INTEL_GTT_GEN ) {case 5 :case 6 : +case 7 : gtt_offset =MB (2 );break ;case 4 :
Signature · 1 line
1.7.9.5
PATCH 11/14 drm/i915: don't enable PPGTT on VLV yet
In reply to Jesse BarnesNeeds some more work and testing.
--- drivers/gpu/drm/i915/i915_drv.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
drivers/gpu/drm/i915/i915_drv.h +1 -1
@@ -1074,7 +1074,7 @@ struct drm_i915_file_private {#define HAS_LLC (dev) (INTEL_INFO(dev)->has_llc)#define I915_NEED_GFX_HWS (dev) (INTEL_INFO(dev)->need_gfx_hws) -#define HAS_ALIASING_PPGTT (dev) (INTEL_INFO(dev)->gen >=6) +#define HAS_ALIASING_PPGTT (dev) (INTEL_INFO(dev)->gen >=6 && !IS_VALLEYVIEW(dev))#define HAS_OVERLAY (dev) (INTEL_INFO(dev)->has_overlay)#define OVERLAY_NEEDS_PHYSICAL (dev) (INTEL_INFO(dev)->overlay_needs_physical)
Signature · 1 line
1.7.9.5
PATCH 12/14 drm/i915: don't account for shared interrupts on VLV
In reply to Jesse BarnesOnly count interrupts we find came from the GPU.
--- drivers/gpu/drm/i915/i915_irq.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-)
drivers/gpu/drm/i915/i915_irq.c +2 -2
@@ -515,8 +515,6 @@ static irqreturn_t valleyview_irq_handler(DRM_IRQ_ARGS)u32 pipe_stats[I915_MAX_PIPES ];bool blc_event; -atomic_inc (&dev_priv->irq_received); -while (true) { iir =I915_READ (VLV_IIR ); gt_iir =I915_READ (GTIIR );
@@ -525,6 +523,8 @@ static irqreturn_t valleyview_irq_handler(DRM_IRQ_ARGS)if (gt_iir ==0 && pm_iir ==0 && iir ==0 ) goto out; +atomic_inc (&dev_priv->irq_received); + ret =IRQ_HANDLED ;snb_gt_irq_handler (dev, dev_priv, gt_iir);
Signature · 1 line
1.7.9.5
Re: [PATCH 12/14] drm/i915: don't account for shared interrupts on VLV
Quoted 3 lines · Jesse Barnes
Only count interrupts we find came from the GPU.
Signed-off-by Jesse Barnes <[email protected]>
We have this on every generation's irq handler this way. I guess we should either fix this everywhere or not bother with it. Dropped for now. -Daniel
Quoted 33 lines
--- drivers/gpu/drm/i915/i915_irq.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-)drivers/gpu/drm/i915/i915_irq.c +2
-2@@ -515,8 +515,6 @@ static irqreturn_t valleyview_irq_handler(DRM_IRQ_ARGS)u32 pipe_stats[I915_MAX_PIPES ];bool blc_event; -atomic_inc (&dev_priv->irq_received); -while (true) { iir =I915_READ (VLV_IIR ); gt_iir =I915_READ (GTIIR );@@ -525,6 +523,8 @@ static irqreturn_t valleyview_irq_handler(DRM_IRQ_ARGS)if (gt_iir ==0 && pm_iir ==0 && iir ==0 ) goto out; +atomic_inc (&dev_priv->irq_received); + ret =IRQ_HANDLED ;snb_gt_irq_handler (dev, dev_priv, gt_iir);Signature · 6 lines
1.7.9.5 _______________________________________________ Intel-gfx mailing list [email protected] http://lists.freedesktop.org/mailman/listinfo/intel-gfx
Signature · 3 lines
Daniel Vetter Mail: [email protected] Mobile: +41 (0)79 365 57 48
A message that is not in the archive (sent off-list or not yet received): 15842_1340198260_4FE1CD73_15842_15371_1_20120620131831.GJ7170@phenom.ffwll.local
PATCH v4 1/1 Added support for the ns2501 DVO
This patch adds support for the ns2501 DVO, found in some older Fujitsu/Siemens Labtops. It is in the state of "works for me".
Includes now proper DPMS support. Includes switching between resolutions - from 640x480 to 1024x768. Currently assumes that the native display resolution is 1024x768.
The ns2501 seems to be rather critical - if the output PLL is not running, the chip doesn't seem to be clocked and then doesn't react on i2c messages. Thus, a quick'n-dirty trick ensures that the DVO is active before submitting any i2c messages to it. This is probably to be reviewed.
Bugzilla: https://bugs.freedesktop.org/show_bug.cgi?id=17902
--- drivers/gpu/drm/i915/Makefile | 1 + drivers/gpu/drm/i915/dvo.h | 1 + drivers/gpu/drm/i915/dvo_ns2501.c | 566 ++++++++++++++++++++++++++++++++++ drivers/gpu/drm/i915/intel_display.c | 4 +- drivers/gpu/drm/i915/intel_dvo.c | 10 +- 5 files changed, 580 insertions(+), 2 deletions(-) create mode 100644 drivers/gpu/drm/i915/dvo_ns2501.c
drivers/gpu/drm/i915/Makefile +1 -0
@@ -39,6 +39,7 @@ i915-y := i915_drv.o i915_dma.o i915_irq.o \ dvo_ivch.o \ dvo_tfp410.o \ dvo_sil164.o \ + dvo_ns2501.o \ i915_gem_dmabuf.o i915-$(CONFIG_COMPAT) += i915_ioc32.o
drivers/gpu/drm/i915/dvo.h +1 -0
@@ -140,5 +140,6 @@ extern struct intel_dvo_dev_ops ch7xxx_ops;extern struct intel_dvo_dev_ops ivch_ops;extern struct intel_dvo_dev_ops tfp410_ops;extern struct intel_dvo_dev_ops ch7017_ops; +extern struct intel_dvo_dev_ops ns2501_ops;#endif /* _INTEL_DVO_H */
drivers/gpu/drm/i915/dvo_ns2501.c new file +566 -0
566 lines not on this page · raw message
drivers/gpu/drm/i915/intel_display.c +3 -1
@@ -1280,8 +1280,10 @@ static void assert_pch_ports_disabled(struct drm_i915_private *dev_priv,* protect mechanism may be enabled. * * Note! This is for pre-ILK only. +* +* Unfortunately needed by dvo_ns2501 since the dvo depends on it running. */ -static void intel_enable_pll (struct drm_i915_private *dev_priv,enum pipe pipe) +void intel_enable_pll (struct drm_i915_private *dev_priv,enum pipe pipe) {int reg;u32 val;
drivers/gpu/drm/i915/intel_dvo.c +9 -1
@@ -37,6 +37,7 @@#define SIL164_ADDR 0x38#define CH7xxx_ADDR 0x76#define TFP410_ADDR 0x38 +#define NS2501_ADDR 0x38static const struct intel_dvo_device intel_dvo_devices[] = { {
@@ -74,7 +75,14 @@ static const struct intel_dvo_device intel_dvo_devices[] = { .slave_addr = 0x75, .gpio = GMBUS_PORT_DPB, .dev_ops = &ch7017_ops, - } + }, + { + .type = INTEL_DVO_CHIP_TMDS, + .name = "ns2501", + .dvo_reg = DVOC, + .slave_addr = NS2501_ADDR, + .dev_ops = &ns2501_ops, + } }; struct intel_dvo {
Signature · 1 line
1.7.2.5
Re: [PATCH v4] Added support for the ns2501 DVO
Quoted 12 lines · Thomas Richter
This patch adds support for the ns2501 DVO, found in some older Fujitsu/Siemens Labtops. It is in the state of "works for me". Includes now proper DPMS support. Includes switching between resolutions - from 640x480 to 1024x768. Currently assumes that the native display resolution is 1024x768.
The ns2501 seems to be rather critical - if the output PLL is not running, the chip doesn't seem to be clocked and then doesn't react on i2c messages. Thus, a quick'n-dirty trick ensures that the DVO is active before submitting any i2c messages to it. This is probably to be reviewed.
Quoted 3 lines
Bugzilla: https://bugs.freedesktop.org/show_bug.cgi?id=17902
Signed-off-by Thomas Richter <[email protected]>
Patch is still massively whitespace-mangling. Just export it to a file with
git format-patch -1 HEAD
and then attach that file, please.
-Daniel
Quoted 673 lines
--- drivers/gpu/drm/i915/Makefile | 1 + drivers/gpu/drm/i915/dvo.h | 1 + drivers/gpu/drm/i915/dvo_ns2501.c | 566 ++++++++++++++++++++++++++++++++++ drivers/gpu/drm/i915/intel_display.c | 4 +- drivers/gpu/drm/i915/intel_dvo.c | 10 +- 5 files changed, 580 insertions(+), 2 deletions(-) create mode 100644 drivers/gpu/drm/i915/dvo_ns2501.cdrivers/gpu/drm/i915/Makefile +1
-0@@ -39,6 +39,7 @@ i915-y := i915_drv.o i915_dma.o i915_irq.o \ dvo_ivch.o \ dvo_tfp410.o \ dvo_sil164.o \ + dvo_ns2501.o \ i915_gem_dmabuf.o i915-$(CONFIG_COMPAT) += i915_ioc32.odrivers/gpu/drm/i915/dvo.h +1
-0@@ -140,5 +140,6 @@ extern struct intel_dvo_dev_ops ch7xxx_ops;extern struct intel_dvo_dev_ops ivch_ops;extern struct intel_dvo_dev_ops tfp410_ops;extern struct intel_dvo_dev_ops ch7017_ops; +extern struct intel_dvo_dev_ops ns2501_ops;#endif /* _INTEL_DVO_H */ drivers/gpu/drm/i915/dvo_ns2501.c new file +80
-0@@ -0,0 +1,566 @@ +/************************************************************************** + +Copyright © 2012 Gilles Dartiguelongue, Thomas Richter + +All Rights Reserved. + +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, sub license, 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 NON-INFRINGEMENT. +IN NO EVENT SHALL THE AUTHOR 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. + +**************************************************************************/ + +#include "dvo.h" +#include "i915_reg.h" +#include "i915_drv.h" + +#define NS2501_VID 0x1305 +#define NS2501_DID 0x6726 + +#define NS2501_VID_LO 0x00 +#define NS2501_VID_HI 0x01 +#define NS2501_DID_LO 0x02 +#define NS2501_DID_HI 0x03 +#define NS2501_REV 0x04 +#define NS2501_RSVD 0x05 +#define NS2501_FREQ_LO 0x06 +#define NS2501_FREQ_HI 0x07 + +#define NS2501_REG8 0x08 +#define NS2501_8_VEN (1<<5) +#define NS2501_8_HEN (1<<4) +#define NS2501_8_DSEL (1<<3) +#define NS2501_8_BPAS (1<<2) +#define NS2501_8_RSVD (1<<1) +#define NS2501_8_PD (1<<0) + +#define NS2501_REG9 0x09 +#define NS2501_9_VLOW (1<<7) +#define NS2501_9_MSEL_MASK (0x7<<4) +#define NS2501_9_TSEL (1<<3) +#define NS2501_9_RSEN (1<<2) +#define NS2501_9_RSVD (1<<1) +#define NS2501_9_MDI (1<<0) + +#define NS2501_REGC 0x0c + +struct ns2501_priv { +//I2CDevRec d; +bool quiet; +int reg_8_shadow; +int reg_8_set; +// Shadow registers for i915 +int dvoc; +int pll_a; +int srcdim; +int fw_blc; +}; + +#define NSPTR (d) ((NS2501Ptr)(d->DriverPrivate.ptr)) + +/* +** Include the PLL launcher prototype +*/ +extern void intel_enable_pll(struct drm_i915_private *dev_priv,enum pipe pipe);
drivers/gpu/drm/i915/dvo_ns2501.c new file +66
-0+ +/* +** For reasons unclear to me, the ns2501 at least on the Fujitsu/Siemens +** laptops does not react on the i2c bus unless +** both the PLL is running and the display is configured in its native +** resolution. +** This function forces the DVO on, and stores the registers it touches. +** Afterwards, registers are restored to regular values. +** +** This is pretty much a hack, though it works. +** Without that, ns2501_readb and ns2501_writeb fail +** when switching the resolution. +*/ + +static void enable_dvo (struct intel_dvo_device *dvo) +{ +struct ns2501_priv *ns = (struct ns2501_priv *)(dvo->dev_priv); +struct i2c_adapter *adapter = dvo->i2c_bus; +struct intel_gmbus *bus =container_of (adapter, + struct intel_gmbus, + adapter); +struct drm_i915_private *dev_priv = bus->dev_priv; + +DRM_DEBUG_KMS ("%s: Trying to re-enable the DVO\n" ,__FUNCTION__); + + ns->dvoc =I915_READ (DVO_C ); + ns->pll_a =I915_READ (_DPLL_A); + ns->srcdim =I915_READ (DVOC_SRCDIM ); + ns->fw_blc =I915_READ (FW_BLC ); + +I915_WRITE (DVOC ,0x10004084 ); +I915_WRITE (_DPLL_A,0xd0820000 ); +I915_WRITE (DVOC_SRCDIM ,0x400300 );// 1024x768 +I915_WRITE (FW_BLC ,0x1080304 ); + +intel_enable_pll (dev_priv,0 ); + +I915_WRITE (DVOC ,0x90004084 ); +} + +/* +** Restore the I915 registers modified by the above +** trigger function. +*/ +static void restore_dvo (struct intel_dvo_device *dvo) +{ +struct i2c_adapter *adapter = dvo->i2c_bus; +struct intel_gmbus *bus =container_of (adapter, + struct intel_gmbus, + adapter); +struct drm_i915_private *dev_priv = bus->dev_priv; +struct ns2501_priv *ns = (struct ns2501_priv *)(dvo->dev_priv); + +I915_WRITE (DVOC ,ns->dvoc); +I915_WRITE (_DPLL_A ,ns->pll_a); +I915_WRITE (DVOC_SRCDIM ,ns->srcdim); +I915_WRITE (FW_BLC ,ns->fw_blc); +} + +/* +** Read a register from the ns2501. +** Returns true if successful, false otherwise. +** If it returns false, it might be wise to enable the +** DVO with the above function. +*/ +static bool ns2501_readb(struct intel_dvo_device *dvo, int addr,
uint8_t*ch)drivers/gpu/drm/i915/dvo_ns2501.c new file +44
-0+{ +struct ns2501_priv *ns = dvo->dev_priv; +struct i2c_adapter *adapter = dvo->i2c_bus; +u8 out_buf[2 ]; +u8 in_buf[2 ]; + +struct i2c_msg msgs[] = { + { + .addr = dvo->slave_addr, + .flags =0 , + .len =1 , + .buf = out_buf, + }, + { + .addr = dvo->slave_addr, + .flags =I2C_M_RD , + .len =1 , + .buf = in_buf, + } + }; + + out_buf[0 ] = addr; + out_buf[1 ] =0 ; + +if (i2c_transfer (adapter, msgs,2 ) ==2 ) { + *ch = in_buf[0 ]; +return true; + }; + +if (!ns->quiet) { +DRM_DEBUG_KMS ("Unable to read register 0x%02x from %s:0x%02x.\n" , + addr, adapter->name, dvo->slave_addr); + } + +return false; +} + +/* +** Write a register to the ns2501. +** Returns true if successful, false otherwise. +** If it returns false, it might be wise to enable the +** DVO with the above function. +*/ +static bool ns2501_writeb(struct intel_dvo_device *dvo, int addr,
uint8_tch)drivers/gpu/drm/i915/dvo_ns2501.c new file +68
-0+{ +struct ns2501_priv *ns = dvo->dev_priv; +struct i2c_adapter *adapter = dvo->i2c_bus; +uint8_t out_buf[2 ]; + +struct i2c_msg msg = { + .addr = dvo->slave_addr, + .flags =0 , + .len =2 , + .buf = out_buf, + }; + + out_buf[0 ] = addr; + out_buf[1 ] = ch; + +if (i2c_transfer (adapter, &msg,1 ) ==1 ) { +return true; + } + +if (!ns->quiet) { +DRM_DEBUG_KMS ("Unable to write register 0x%02x to %s:%d\n" , + addr, adapter->name, dvo->slave_addr); + } + +return false; +} + +/* National Semiconductor 2501 driver for chip on i2c bus +** scan for the chip on the bus. +** Hope the VBIOS initialized the PLL correctly so we can +** talk to it. If not, it will not be seen and not detected. +** Bummer! +*/ +static bool ns2501_init (struct intel_dvo_device *dvo, +struct i2c_adapter *adapter) +{ +/* this will detect the NS2501 chip on the specified i2c bus */ +struct ns2501_priv *ns; +unsigned char ch; + + ns =kzalloc (sizeof (struct ns2501_priv ),GFP_KERNEL ); +if (ns ==NULL ) +return false; + + dvo->i2c_bus = adapter; + dvo->dev_priv = ns; + ns->quiet = true; + +if (!ns2501_readb (dvo,NS2501_VID_LO , &ch)) + goto out; + +if (ch != (NS2501_VID &0xff )) { +DRM_DEBUG_KMS ("ns2501 not detected got %d: from %s Slave %d.\n" , + ch, adapter->name, dvo->slave_addr); + goto out; + } + +if (!ns2501_readb (dvo,NS2501_DID_LO , &ch)) + goto out; + +if (ch != (NS2501_DID &0xff )) { +DRM_DEBUG_KMS ("ns2501 not detected got %d: from %s Slave %d.\n" , + ch, adapter->name, dvo->slave_addr); + goto out; + } + ns->quiet = false; + ns->reg_8_set =0 ; + ns->reg_8_shadow = NS2501_8_PD | NS2501_8_BPAS | NS2501_8_VEN |
NS2501_8_HEN;drivers/gpu/drm/i915/dvo_ns2501.c new file +10
-0+ +DRM_DEBUG_KMS ("init ns2501 dvo controller successfully!\n" ); +return true; + + out: +kfree (ns); +return false; +} + +static enum drm_connector_status ns2501_detect(struct
intel_dvo_device*dvo)drivers/gpu/drm/i915/dvo_ns2501.c new file +15
-0+{ +/* +** This is a Laptop display, it doesn't have hotplugging. +** Even if not, the detection bit of the 2501 is unreliable as +** it only works for some display types. +** It is even more unreliable as the PLL must be active for +** allowing reading from the chiop. +*/ +return connector_status_connected; +} + +static enum drm_mode_status ns2501_mode_valid (struct intel_dvo_device *dvo, +struct drm_display_mode *mode) +{ + DRM_DEBUG_KMS("%s: is mode valid(hdisplay=%d,htotal=%d,vdisplay=%d,vtotal=%d)\n",__FUNCTION__,
drivers/gpu/drm/i915/dvo_ns2501.c new file +27
-0+ mode->hdisplay,mode->htotal,mode->vdisplay,mode->vtotal); + + +/* +** Currently, these are all the modes I have data from. +** More might exist. Unclear how to find the native resolution +** of the panel in here so we could always accept it +** by disabling the scaler. +*/ +if ((mode->hdisplay ==800 && mode->vdisplay ==600 ) || + (mode->hdisplay ==640 && mode->vdisplay ==480 ) || + (mode->hdisplay ==1024 && mode->vdisplay ==768 )) { +return MODE_OK ; + }else { +return MODE_ONE_SIZE ;/* Is this a reasonable error? */ + } +} + +static void ns2501_mode_set (struct intel_dvo_device *dvo, +struct drm_display_mode *mode, +struct drm_display_mode *adjusted_mode) +{ +bool ok; +bool restore = false; +struct ns2501_priv *ns = (struct ns2501_priv *)(dvo->dev_priv); + + DRM_DEBUG_KMS("%s: set mode(hdisplay=%d,htotal=%d,vdisplay=%d,vtotal=%d).\n",__FUNCTION__,
drivers/gpu/drm/i915/dvo_ns2501.c new file +4
-0+ mode->hdisplay,mode->htotal,mode->vdisplay,mode->vtotal); + +/* +** Where do I find the native resolution for which scaling is not required???
drivers/gpu/drm/i915/dvo_ns2501.c new file +2
-0+ ** + ** First trigger the DVO on as otherwise the chip does not appearon the i2c
drivers/gpu/drm/i915/dvo_ns2501.c new file +20
-0+** bus. +*/ + do { + ok = true; + + if (mode->hdisplay == 800 && mode->vdisplay == 600) { + /* mode 277 */ + ns->reg_8_shadow &= ~NS2501_8_BPAS; + DRM_DEBUG_KMS("%s: switching to 800x600\n",__FUNCTION__); + + /* + ** No, I do not know where this data comes from. + ** It is just what the video bios left in the DVO, so + ** I'm just copying it here over. + ** This also means that I cannot support any other modes + ** except the ones supported by the bios. + */ + ok &= ns2501_writeb(dvo, 0x11, 0xc8); // 0xc7 also works. + ok &= ns2501_writeb(dvo, 0x1b, 0x19); + ok &= ns2501_writeb(dvo, 0x1c, 0x62); // VBIOS left 0x64here, but
0x62works nicerdrivers/gpu/drm/i915/dvo_ns2501.c new file +15
-0+ ok &=ns2501_writeb (dvo,0x1d ,0x02 ); + + ok &=ns2501_writeb (dvo,0x34 ,0x03 ); + ok &=ns2501_writeb (dvo,0x35 ,0xff ); + + ok &=ns2501_writeb (dvo,0x80 ,0x27 ); + ok &=ns2501_writeb (dvo,0x81 ,0x03 ); + ok &=ns2501_writeb (dvo,0x82 ,0x41 ); + ok &=ns2501_writeb (dvo,0x83 ,0x05 ); + + ok &=ns2501_writeb (dvo,0x8d ,0x02 ); + ok &=ns2501_writeb (dvo,0x8e ,0x04 ); + ok &=ns2501_writeb (dvo,0x8f ,0x00 ); + + ok &=ns2501_writeb (dvo,0x90 ,0xfe );/* vertical. VBIOS left
0xffhere, but0xfeworks better */drivers/gpu/drm/i915/dvo_ns2501.c new file +10
-0+ ok &=ns2501_writeb (dvo,0x91 ,0x07 ); + ok &=ns2501_writeb (dvo,0x94 ,0x00 ); + ok &=ns2501_writeb (dvo,0x95 ,0x00 ); + + ok &=ns2501_writeb (dvo,0x96 ,0x00 ); + + ok &=ns2501_writeb (dvo,0x99 ,0x00 ); + ok &=ns2501_writeb (dvo,0x9a ,0x88 ); + + ok &=ns2501_writeb (dvo,0x9c ,0x23 );/* Looks like first and last line of the image. */
drivers/gpu/drm/i915/dvo_ns2501.c new file +140
-0+ ok &=ns2501_writeb (dvo,0x9d ,0x00 ); + ok &=ns2501_writeb (dvo,0x9e ,0x25 ); + ok &=ns2501_writeb (dvo,0x9f ,0x03 ); + + ok &=ns2501_writeb (dvo,0xa4 ,0x80 ); + + ok &=ns2501_writeb (dvo,0xb6 ,0x00 ); + + ok &=ns2501_writeb (dvo,0xb9 ,0xc8 );/* horizontal? */ + ok &=ns2501_writeb (dvo,0xba ,0x00 );/* horizontal? */ + + ok &=ns2501_writeb (dvo,0xc0 ,0x05 );/* horizontal? */ + ok &=ns2501_writeb (dvo,0xc1 ,0xd7 ); + + ok &=ns2501_writeb (dvo,0xc2 ,0x00 ); + ok &=ns2501_writeb (dvo,0xc3 ,0xf8 ); + + ok &=ns2501_writeb (dvo,0xc4 ,0x03 ); + ok &=ns2501_writeb (dvo,0xc5 ,0x1a ); + + ok &=ns2501_writeb (dvo,0xc6 ,0x00 ); + ok &=ns2501_writeb (dvo,0xc7 ,0x73 ); + ok &=ns2501_writeb (dvo,0xc8 ,0x02 ); + + }else if (mode->hdisplay ==640 && mode->vdisplay ==480 ) { +/* mode 274 */ +DRM_DEBUG_KMS ("%s: switching to 640x480\n" ,__FUNCTION__); +/* +** No, I do not know where this data comes from. +** It is just what the video bios left in the DVO, so +** I'm just copying it here over. +** This also means that I cannot support any other modes +** except the ones supported by the bios. +*/ + ns->reg_8_shadow &= ~NS2501_8_BPAS ; + + ok &=ns2501_writeb (dvo,0x11 ,0xa0 ); + ok &=ns2501_writeb (dvo,0x1b ,0x11 ); + ok &=ns2501_writeb (dvo,0x1c ,0x54 ); + ok &=ns2501_writeb (dvo,0x1d ,0x03 ); + + ok &=ns2501_writeb (dvo,0x34 ,0x03 ); + ok &=ns2501_writeb (dvo,0x35 ,0xff ); + + ok &=ns2501_writeb (dvo,0x80 ,0xff ); + ok &=ns2501_writeb (dvo,0x81 ,0x07 ); + ok &=ns2501_writeb (dvo,0x82 ,0x3d ); + ok &=ns2501_writeb (dvo,0x83 ,0x05 ); + + ok &=ns2501_writeb (dvo,0x8d ,0x02 ); + ok &=ns2501_writeb (dvo,0x8e ,0x10 ); + ok &=ns2501_writeb (dvo,0x8f ,0x00 ); + + ok &=ns2501_writeb (dvo,0x90 ,0xff );/* vertical */ + ok &=ns2501_writeb (dvo,0x91 ,0x07 ); + ok &=ns2501_writeb (dvo,0x94 ,0x00 ); + ok &=ns2501_writeb (dvo,0x95 ,0x00 ); + + ok &=ns2501_writeb (dvo,0x96 ,0x05 ); + + ok &=ns2501_writeb (dvo,0x99 ,0x00 ); + ok &=ns2501_writeb (dvo,0x9a ,0x88 ); + + ok &=ns2501_writeb (dvo,0x9c ,0x24 ); + ok &=ns2501_writeb (dvo,0x9d ,0x00 ); + ok &=ns2501_writeb (dvo,0x9e ,0x25 ); + ok &=ns2501_writeb (dvo,0x9f ,0x03 ); + + ok &=ns2501_writeb (dvo,0xa4 ,0x84 ); + + ok &=ns2501_writeb (dvo,0xb6 ,0x09 ); + + ok &=ns2501_writeb (dvo,0xb9 ,0xa0 );/* horizontal? */ + ok &=ns2501_writeb (dvo,0xba ,0x00 );/* horizontal? */ + + ok &=ns2501_writeb (dvo,0xc0 ,0x05 );/* horizontal? */ + ok &=ns2501_writeb (dvo,0xc1 ,0x90 ); + + ok &=ns2501_writeb (dvo,0xc2 ,0x00 ); + ok &=ns2501_writeb (dvo,0xc3 ,0x0f ); + + ok &=ns2501_writeb (dvo,0xc4 ,0x03 ); + ok &=ns2501_writeb (dvo,0xc5 ,0x16 ); + + ok &=ns2501_writeb (dvo,0xc6 ,0x00 ); + ok &=ns2501_writeb (dvo,0xc7 ,0x02 ); + ok &=ns2501_writeb (dvo,0xc8 ,0x02 ); + + }else if (mode->hdisplay ==1024 && mode->vdisplay ==768 ) { +/* mode 280 */ +DRM_DEBUG_KMS ("%s: switching to 1024x768\n" ,__FUNCTION__); +/* +** This might or might not work, actually. I'm silently +** assuming here that the native panel resolution is +** 1024x768. If not, then this leaves the scaler disabled +** generating a picture that is likely not the expected. +** +** Problem is that I do not know where to take the panel +** dimensions from. +** +** Enable the bypass, scaling not required. +** +** The scaler registers are irrelevant here.... +** +*/ + ns->reg_8_shadow |=NS2501_8_BPAS ; + ok &=ns2501_writeb (dvo,0x37 ,0x44 ); + }else { +/* Data not known. Bummer! +** Hopefully, the code should not go here +** as mode_OK delivered no other modes. +*/ + ns->reg_8_shadow |=NS2501_8_BPAS ; + } + ok &=ns2501_writeb (dvo,NS2501_REG8 , ns->reg_8_shadow); + +if (!ok) { +if (restore) +restore_dvo (dvo); +enable_dvo (dvo); + restore = true; + } + }while (!ok); +/* +** Restore the old i915 registers before +** forcing the ns2501 on. +*/ +if (restore) +restore_dvo (dvo); +} + +/* set the NS2501 power state */ +static void ns2501_dpms (struct intel_dvo_device *dvo,int mode) +{ +bool ok; +bool restore = false; +struct ns2501_priv *ns = (struct ns2501_priv *)(dvo->dev_priv); +unsigned char ch; + + DRM_DEBUG_KMS("%s: Trying set the dpms of the DVO to%d\n",__FUNCTION__,mode);
drivers/gpu/drm/i915/dvo_ns2501.c new file +16
-0+ + ch = ns->reg_8_shadow; + + if (mode == DRM_MODE_DPMS_ON) + ch |= NS2501_8_PD; + else + ch &= ~NS2501_8_PD; + + if (ns->reg_8_set == 0 || ns->reg_8_shadow != ch) { + ns->reg_8_set = 1; + ns->reg_8_shadow = ch; + + do { + ok = true; + ok &= ns2501_writeb(dvo, NS2501_REG8, ch); + ok &= ns2501_writeb(dvo, 0x34 ,(mode ==DRM_MODE_DPMS_ON)?(0x03):(0x00));
+ ok &= ns2501_writeb(dvo,0x35,(mode ==
DRM_MODE_DPMS_ON)?(0xff):(0x00));drivers/gpu/drm/i915/dvo_ns2501.c new file +48
-0+if (!ok) { +if (restore) +restore_dvo (dvo); +enable_dvo (dvo); + restore = true; + } + }while (!ok); + +if (restore) +restore_dvo (dvo); + } +} + +static void ns2501_dump_regs (struct intel_dvo_device *dvo) +{ +uint8_t val; + +ns2501_readb (dvo,NS2501_FREQ_LO , &val); +DRM_LOG_KMS ("NS2501_FREQ_LO: 0x%02x\n" , val); +ns2501_readb (dvo,NS2501_FREQ_HI , &val); +DRM_LOG_KMS ("NS2501_FREQ_HI: 0x%02x\n" , val); +ns2501_readb (dvo,NS2501_REG8 , &val); +DRM_LOG_KMS ("NS2501_REG8: 0x%02x\n" , val); +ns2501_readb (dvo,NS2501_REG9 , &val); +DRM_LOG_KMS ("NS2501_REG9: 0x%02x\n" , val); +ns2501_readb (dvo,NS2501_REGC , &val); +DRM_LOG_KMS ("NS2501_REGC: 0x%02x\n" , val); +} + +static void ns2501_destroy (struct intel_dvo_device *dvo) +{ +struct ns2501_priv *ns = dvo->dev_priv; + +if (ns) { +kfree (ns); + dvo->dev_priv =NULL ; + } +} + +struct intel_dvo_dev_ops ns2501_ops = { + .init = ns2501_init, + .detect = ns2501_detect, + .mode_valid = ns2501_mode_valid, + .mode_set = ns2501_mode_set, + .dpms = ns2501_dpms, + .dump_regs = ns2501_dump_regs, + .destroy = ns2501_destroy, +};drivers/gpu/drm/i915/intel_display.c +3
-1@@ -1280,8 +1280,10 @@ static void assert_pch_ports_disabled(structdrm_i915_private *dev_priv, * protect mechanism may be enabled. * * Note! This is for pre-ILK only. +* +* Unfortunately needed by dvo_ns2501 since the dvo depends on it running. */ -static void intel_enable_pll (struct drm_i915_private *dev_priv, enum pipe pipe) +void intel_enable_pll (struct drm_i915_private *dev_priv,enum pipe pipe) {drivers/gpu/drm/i915/intel_display.c +0
-0int reg;u32 val;drivers/gpu/drm/i915/intel_dvo.c +9
-1@@ -37,6 +37,7 @@#define SIL164_ADDR 0x38#define CH7xxx_ADDR 0x76#define TFP410_ADDR 0x38 +#define NS2501_ADDR 0x38static const struct intel_dvo_device intel_dvo_devices[] = { {@@ -74,7 +75,14 @@ static const struct intel_dvo_device intel_dvo_devices[] = { .slave_addr =0x75 , .gpio =GMBUS_PORT_DPB , .dev_ops = &ch7017_ops, - } + }, + { + .type = INTEL_DVO_CHIP_TMDS, + .name = "ns2501", + .dvo_reg = DVOC, + .slave_addr = NS2501_ADDR, + .dev_ops = &ns2501_ops, + } };struct
intel_dvo{Signature · 1 line
1.7.2.5
Signature · 3 lines
Daniel Vetter Mail: [email protected] Mobile: +41 (0)79 365 57 48
Re: [PATCH v4] Added support for the ns2501 DVO
Dear Thomas,
thanks for the iteration.
Am Mittwoch, den 20.06.2012, 20:03 +0200 schrieb Daniel Vetter:
Quoted 2 lines · Thomas Richter
Quoted 1 line
This patch adds support for the ns2501 DVO, found in some older
Please also use present tense in the commit summary.
git commit --amend
should do the trick.
Quoted 1 line
Quoted 1 line
Fujitsu/Siemens Labtops. It is in the state of "works for me".
laptops
Quoted 12 lines
Quoted 12 lines
Includes now proper DPMS support. Includes switching between resolutions - from 640x480 to 1024x768. Currently assumes that the native display resolution is 1024x768.
The ns2501 seems to be rather critical - if the output PLL is not running, the chip doesn't seem to be clocked and then doesn't react on i2c messages. Thus, a quick'n-dirty trick ensures that the DVO is active before submitting any i2c messages to it. This is probably to be reviewed.
Bugzilla: https://bugs.freedesktop.org/show_bug.cgi?id=17902
Quoted 8 lines
Quoted 1 line
Signed-off-by Thomas Richter <[email protected]>Patch is still massively whitespace-mangling. Just export it to a file with
git format-patch -1 HEAD
and then attach that file, please.
Thomas, Thunderbird should allow you to select certain parts of the message and disable automatic line wrapping for that.
[…]
Thanks,
Paul
_______________________________________________
Intel-gfx mailing list
[email protected]
http://lists.freedesktop.org/mailman/listinfo/intel-gfx
PATCH 13/14 drm/i915: fix initial IRQ masking on VLV
In reply to Jesse BarnesWe can leave vblank interrupts masked but enabled so we're not dependent on the first client to toggle the disable timer. We can also mask all render based interrupts, since the ring code will handle unmasking them for us.
--- drivers/gpu/drm/i915/i915_irq.c | 12 +++++++++--- 1 file changed, 9 insertions(+), 3 deletions(-)
drivers/gpu/drm/i915/i915_irq.c +9 -3
@@ -1889,7 +1889,13 @@ static int valleyview_irq_postinstall(struct drm_device *dev)I915_DISPLAY_PIPE_B_EVENT_INTERRUPT |I915_DISPLAY_PIPE_B_VBLANK_INTERRUPT ; - dev_priv->irq_mask = ~enable_mask; +/* +*Leave vblank interrupts masked initially. enable/disable will +* toggle them based on usage. +*/ + dev_priv->irq_mask = (~enable_mask) | +I915_DISPLAY_PIPE_A_VBLANK_INTERRUPT | +I915_DISPLAY_PIPE_B_VBLANK_INTERRUPT ; dev_priv->pipestat[0 ] =0 ; dev_priv->pipestat[1 ] =0 ;
@@ -1925,11 +1931,11 @@ static int valleyview_irq_postinstall(struct drm_device *dev)GT_SYNC_STATUS |GT_USER_INTERRUPT ; - dev_priv->gt_irq_mask = ~render_irqs; + dev_priv->gt_irq_mask = ~0 ;I915_WRITE (GTIIR ,I915_READ (GTIIR ));I915_WRITE (GTIIR ,I915_READ (GTIIR )); -I915_WRITE (GTIMR ,0 ); +I915_WRITE (GTIMR , dev_priv->gt_irq_mask);I915_WRITE (GTIER , render_irqs);POSTING_READ (GTIER );
Signature · 1 line
1.7.9.5
Re: [PATCH 13/14] drm/i915: fix initial IRQ masking on VLV
Quoted 19 lines · Jesse Barnes
We can leave vblank interrupts masked but enabled so we're not dependent on the first client to toggle the disable timer. We can also mask all render based interrupts, since the ring code will handle unmasking them for us.
Signed-off-by Jesse Barnes <[email protected]>--- drivers/gpu/drm/i915/i915_irq.c | 12 +++++++++--- 1 file changed, 9 insertions(+), 3 deletions(-)drivers/gpu/drm/i915/i915_irq.c +0
-1@@ -1889,7 +1889,13 @@ static int valleyview_irq_postinstall(struct drm_device *dev)I915_DISPLAY_PIPE_B_EVENT_INTERRUPT |I915_DISPLAY_PIPE_B_VBLANK_INTERRUPT ; - dev_priv->irq_mask = ~enable_mask;
drivers/gpu/drm/i915/i915_irq.c static int valleyview_irq_postinstall(struct drm_device *dev) · line 1901
Quoted 10 lines
drivers/gpu/drm/i915/i915_irq.c +7
-0+/* +*Leave vblank interrupts masked initially. enable/disable will +* toggle them based on usage. +*/ + dev_priv->irq_mask = (~enable_mask) | +I915_DISPLAY_PIPE_A_VBLANK_INTERRUPT | +I915_DISPLAY_PIPE_B_VBLANK_INTERRUPT ; dev_priv->pipestat[0 ] =0 ; dev_priv->pipestat[1 ] =0 ;
Please squash this hunk here with the vlv pageflip patch - this little fumble decently confused me while reviewing the patchflip patch.
drivers/gpu/drm/i915/i915_irq.c static int valleyview_irq_postinstall(struct drm_device *dev) · line 1940
Quoted 13 lines
drivers/gpu/drm/i915/i915_irq.c +2
-2@@ -1925,11 +1931,11 @@ static int valleyview_irq_postinstall(struct drm_device *dev)GT_SYNC_STATUS |GT_USER_INTERRUPT ; - dev_priv->gt_irq_mask = ~render_irqs; + dev_priv->gt_irq_mask = ~0 ;I915_WRITE (GTIIR ,I915_READ (GTIIR ));I915_WRITE (GTIIR ,I915_READ (GTIIR )); -I915_WRITE (GTIMR ,0 ); +I915_WRITE (GTIMR , dev_priv->gt_irq_mask);I915_WRITE (GTIER , render_irqs);POSTING_READ (GTIER );
Presuming I haven't missed anything, render_irqs is now an unused variable. Please also rip that out, but leave the gt_irq frobbing in a separate patch.
-Daniel
Quoted 8 lines
Signature · 7 lines
-- 1.7.9.5 _______________________________________________ Intel-gfx mailing list [email protected] http://lists.freedesktop.org/mailman/listinfo/intel-gfx
Signature · 3 lines
Daniel Vetter Mail: [email protected] Mobile: +41 (0)79 365 57 48
PATCH 14/14 drm/i915: bind driver to ValleyView chipsets
In reply to Jesse BarnesWith the code in place, we can bind the driver, should make bisect possible.
--- drivers/gpu/drm/i915/i915_drv.c | 3 +++ 1 file changed, 3 insertions(+)
drivers/gpu/drm/i915/i915_drv.c +3 -0
@@ -352,6 +352,9 @@ static const struct pci_device_id pciidlist[] = { /* aka */INTEL_VGA_DEVICE (0x0406 , &intel_haswell_m_info),/* GT1 mobile */ INTEL_VGA_DEVICE (0x0416 , &intel_haswell_m_info),/* GT2 mobile */ INTEL_VGA_DEVICE (0x0c16 , &intel_haswell_d_info),/* SDV */ +INTEL_VGA_DEVICE (0x0f30 , &intel_valleyview_m_info), +INTEL_VGA_DEVICE (0x0157 , &intel_valleyview_m_info), +INTEL_VGA_DEVICE (0x0155 , &intel_valleyview_d_info), {0, 0, 0} };
Signature · 1 line
1.7.9.5
Re: [PATCH 14/14] drm/i915: bind driver to ValleyView chipsets
Quoted 3 lines · Jesse Barnes
With the code in place, we can bind the driver, should make bisect possible.
Signed-off-by Jesse Barnes <[email protected]>
Ok, I've merged most of these patches, safe for the pageflip/irq stuff (bikesheds dropped in separate mails) and obviously patch 14. Thanks for the patches.
-Daniel
Quoted 25 lines
--- drivers/gpu/drm/i915/i915_drv.c | 3 +++ 1 file changed, 3 insertions(+)drivers/gpu/drm/i915/i915_drv.c +3
-1@@ -352,6 +352,9 @@ static const struct pci_device_id pciidlist[] = { /* aka */INTEL_VGA_DEVICE (0x0406 , &intel_haswell_m_info),/* GT1 mobile */ INTEL_VGA_DEVICE (0x0416 , &intel_haswell_m_info),/* GT2 mobile */ INTEL_VGA_DEVICE (0x0c16 , &intel_haswell_d_info),/* SDV */ +INTEL_VGA_DEVICE (0x0f30 , &intel_valleyview_m_info), +INTEL_VGA_DEVICE (0x0157 , &intel_valleyview_m_info), +INTEL_VGA_DEVICE (0x0155 , &intel_valleyview_d_info), {0, 0, 0} }; --1.7.9.5
_______________________________________________
Intel-gfx mailing list
[email protected]
http://lists.freedesktop.org/mailman/listinfo/intel-gfx
Signature · 3 lines
Daniel Vetter Mail: [email protected] Mobile: +41 (0)79 365 57 48