Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Support
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in / Register
Toggle navigation
L
linux
Project overview
Project overview
Details
Activity
Releases
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Issues
0
Issues
0
List
Boards
Labels
Milestones
Merge Requests
0
Merge Requests
0
Analytics
Analytics
Repository
Value Stream
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Create a new issue
Commits
Issue Boards
Open sidebar
nexedi
linux
Commits
9a1f5780
Commit
9a1f5780
authored
Oct 20, 2011
by
Keith Packard
Browse files
Options
Browse Files
Download
Plain Diff
Merge branch 'fix-pch-refclk' into foo
parents
86a3073e
9fb526db
Changes
5
Hide whitespace changes
Inline
Side-by-side
Showing
5 changed files
with
115 additions
and
60 deletions
+115
-60
drivers/gpu/drm/i915/i915_drv.c
drivers/gpu/drm/i915/i915_drv.c
+5
-2
drivers/gpu/drm/i915/i915_drv.h
drivers/gpu/drm/i915/i915_drv.h
+2
-0
drivers/gpu/drm/i915/intel_bios.c
drivers/gpu/drm/i915/intel_bios.c
+10
-3
drivers/gpu/drm/i915/intel_bios.h
drivers/gpu/drm/i915/intel_bios.h
+7
-2
drivers/gpu/drm/i915/intel_display.c
drivers/gpu/drm/i915/intel_display.c
+91
-53
No files found.
drivers/gpu/drm/i915/i915_drv.c
View file @
9a1f5780
...
@@ -79,11 +79,11 @@ MODULE_PARM_DESC(lvds_downclock,
...
@@ -79,11 +79,11 @@ MODULE_PARM_DESC(lvds_downclock,
"Use panel (LVDS/eDP) downclocking for power savings "
"Use panel (LVDS/eDP) downclocking for power savings "
"(default: false)"
);
"(default: false)"
);
unsigned
int
i915_panel_use_ssc
__read_mostly
=
1
;
unsigned
int
i915_panel_use_ssc
__read_mostly
=
-
1
;
module_param_named
(
lvds_use_ssc
,
i915_panel_use_ssc
,
int
,
0600
);
module_param_named
(
lvds_use_ssc
,
i915_panel_use_ssc
,
int
,
0600
);
MODULE_PARM_DESC
(
lvds_use_ssc
,
MODULE_PARM_DESC
(
lvds_use_ssc
,
"Use Spread Spectrum Clock with panels [LVDS/eDP] "
"Use Spread Spectrum Clock with panels [LVDS/eDP] "
"(default:
true
)"
);
"(default:
auto from VBT
)"
);
int
i915_vbt_sdvo_panel_type
__read_mostly
=
-
1
;
int
i915_vbt_sdvo_panel_type
__read_mostly
=
-
1
;
module_param_named
(
vbt_sdvo_panel_type
,
i915_vbt_sdvo_panel_type
,
int
,
0600
);
module_param_named
(
vbt_sdvo_panel_type
,
i915_vbt_sdvo_panel_type
,
int
,
0600
);
...
@@ -471,6 +471,9 @@ static int i915_drm_thaw(struct drm_device *dev)
...
@@ -471,6 +471,9 @@ static int i915_drm_thaw(struct drm_device *dev)
error
=
i915_gem_init_ringbuffer
(
dev
);
error
=
i915_gem_init_ringbuffer
(
dev
);
mutex_unlock
(
&
dev
->
struct_mutex
);
mutex_unlock
(
&
dev
->
struct_mutex
);
if
(
HAS_PCH_SPLIT
(
dev
))
ironlake_init_pch_refclk
(
dev
);
drm_mode_config_reset
(
dev
);
drm_mode_config_reset
(
dev
);
drm_irq_install
(
dev
);
drm_irq_install
(
dev
);
...
...
drivers/gpu/drm/i915/i915_drv.h
View file @
9a1f5780
...
@@ -358,6 +358,7 @@ typedef struct drm_i915_private {
...
@@ -358,6 +358,7 @@ typedef struct drm_i915_private {
unsigned
int
lvds_vbt
:
1
;
unsigned
int
lvds_vbt
:
1
;
unsigned
int
int_crt_support
:
1
;
unsigned
int
int_crt_support
:
1
;
unsigned
int
lvds_use_ssc
:
1
;
unsigned
int
lvds_use_ssc
:
1
;
unsigned
int
display_clock_mode
:
1
;
int
lvds_ssc_freq
;
int
lvds_ssc_freq
;
struct
{
struct
{
int
rate
;
int
rate
;
...
@@ -1301,6 +1302,7 @@ extern int intel_modeset_vga_set_state(struct drm_device *dev, bool state);
...
@@ -1301,6 +1302,7 @@ extern int intel_modeset_vga_set_state(struct drm_device *dev, bool state);
extern
bool
intel_fbc_enabled
(
struct
drm_device
*
dev
);
extern
bool
intel_fbc_enabled
(
struct
drm_device
*
dev
);
extern
void
intel_disable_fbc
(
struct
drm_device
*
dev
);
extern
void
intel_disable_fbc
(
struct
drm_device
*
dev
);
extern
bool
ironlake_set_drps
(
struct
drm_device
*
dev
,
u8
val
);
extern
bool
ironlake_set_drps
(
struct
drm_device
*
dev
,
u8
val
);
extern
void
ironlake_init_pch_refclk
(
struct
drm_device
*
dev
);
extern
void
ironlake_enable_rc6
(
struct
drm_device
*
dev
);
extern
void
ironlake_enable_rc6
(
struct
drm_device
*
dev
);
extern
void
gen6_set_rps
(
struct
drm_device
*
dev
,
u8
val
);
extern
void
gen6_set_rps
(
struct
drm_device
*
dev
,
u8
val
);
extern
void
intel_detect_pch
(
struct
drm_device
*
dev
);
extern
void
intel_detect_pch
(
struct
drm_device
*
dev
);
...
...
drivers/gpu/drm/i915/intel_bios.c
View file @
9a1f5780
/*
/*
* Copyright 2006 Intel Corporation
* Copyright
©
2006 Intel Corporation
*
*
* Permission is hereby granted, free of charge, to any person obtaining a
* Permission is hereby granted, free of charge, to any person obtaining a
* copy of this software and associated documentation files (the "Software"),
* copy of this software and associated documentation files (the "Software"),
...
@@ -309,6 +309,13 @@ parse_general_features(struct drm_i915_private *dev_priv,
...
@@ -309,6 +309,13 @@ parse_general_features(struct drm_i915_private *dev_priv,
dev_priv
->
lvds_use_ssc
=
general
->
enable_ssc
;
dev_priv
->
lvds_use_ssc
=
general
->
enable_ssc
;
dev_priv
->
lvds_ssc_freq
=
dev_priv
->
lvds_ssc_freq
=
intel_bios_ssc_frequency
(
dev
,
general
->
ssc_freq
);
intel_bios_ssc_frequency
(
dev
,
general
->
ssc_freq
);
dev_priv
->
display_clock_mode
=
general
->
display_clock_mode
;
DRM_DEBUG_KMS
(
"BDB_GENERAL_FEATURES int_tv_support %d int_crt_support %d lvds_use_ssc %d lvds_ssc_freq %d display_clock_mode %d
\n
"
,
dev_priv
->
int_tv_support
,
dev_priv
->
int_crt_support
,
dev_priv
->
lvds_use_ssc
,
dev_priv
->
lvds_ssc_freq
,
dev_priv
->
display_clock_mode
);
}
}
}
}
...
@@ -610,7 +617,7 @@ init_vbt_defaults(struct drm_i915_private *dev_priv)
...
@@ -610,7 +617,7 @@ init_vbt_defaults(struct drm_i915_private *dev_priv)
/* Default to using SSC */
/* Default to using SSC */
dev_priv
->
lvds_use_ssc
=
1
;
dev_priv
->
lvds_use_ssc
=
1
;
dev_priv
->
lvds_ssc_freq
=
intel_bios_ssc_frequency
(
dev
,
1
);
dev_priv
->
lvds_ssc_freq
=
intel_bios_ssc_frequency
(
dev
,
1
);
DRM_DEBUG
(
"Set default to SSC at %dMHz
\n
"
,
dev_priv
->
lvds_ssc_freq
);
DRM_DEBUG
_KMS
(
"Set default to SSC at %dMHz
\n
"
,
dev_priv
->
lvds_ssc_freq
);
/* eDP data */
/* eDP data */
dev_priv
->
edp
.
bpp
=
18
;
dev_priv
->
edp
.
bpp
=
18
;
...
@@ -639,7 +646,7 @@ intel_parse_bios(struct drm_device *dev)
...
@@ -639,7 +646,7 @@ intel_parse_bios(struct drm_device *dev)
if
(
dev_priv
->
opregion
.
vbt
)
{
if
(
dev_priv
->
opregion
.
vbt
)
{
struct
vbt_header
*
vbt
=
dev_priv
->
opregion
.
vbt
;
struct
vbt_header
*
vbt
=
dev_priv
->
opregion
.
vbt
;
if
(
memcmp
(
vbt
->
signature
,
"$VBT"
,
4
)
==
0
)
{
if
(
memcmp
(
vbt
->
signature
,
"$VBT"
,
4
)
==
0
)
{
DRM_DEBUG_
DRIVER
(
"Using VBT from OpRegion: %20s
\n
"
,
DRM_DEBUG_
KMS
(
"Using VBT from OpRegion: %20s
\n
"
,
vbt
->
signature
);
vbt
->
signature
);
bdb
=
(
struct
bdb_header
*
)((
char
*
)
vbt
+
vbt
->
bdb_offset
);
bdb
=
(
struct
bdb_header
*
)((
char
*
)
vbt
+
vbt
->
bdb_offset
);
}
else
}
else
...
...
drivers/gpu/drm/i915/intel_bios.h
View file @
9a1f5780
...
@@ -120,7 +120,9 @@ struct bdb_general_features {
...
@@ -120,7 +120,9 @@ struct bdb_general_features {
u8
ssc_freq
:
1
;
u8
ssc_freq
:
1
;
u8
enable_lfp_on_override
:
1
;
u8
enable_lfp_on_override
:
1
;
u8
disable_ssc_ddt
:
1
;
u8
disable_ssc_ddt
:
1
;
u8
rsvd8
:
3
;
/* finish byte */
u8
rsvd7
:
1
;
u8
display_clock_mode
:
1
;
u8
rsvd8
:
1
;
/* finish byte */
/* bits 3 */
/* bits 3 */
u8
disable_smooth_vision
:
1
;
u8
disable_smooth_vision
:
1
;
...
@@ -133,7 +135,10 @@ struct bdb_general_features {
...
@@ -133,7 +135,10 @@ struct bdb_general_features {
/* bits 5 */
/* bits 5 */
u8
int_crt_support
:
1
;
u8
int_crt_support
:
1
;
u8
int_tv_support
:
1
;
u8
int_tv_support
:
1
;
u8
rsvd11
:
6
;
/* finish byte */
u8
int_efp_support
:
1
;
u8
dp_ssc_enb
:
1
;
/* PCH attached eDP supports SSC */
u8
dp_ssc_freq
:
1
;
/* SSC freq for PCH attached eDP */
u8
rsvd11
:
3
;
/* finish byte */
}
__attribute__
((
packed
));
}
__attribute__
((
packed
));
/* pre-915 */
/* pre-915 */
...
...
drivers/gpu/drm/i915/intel_display.c
View file @
9a1f5780
...
@@ -4585,7 +4585,9 @@ static void intel_update_watermarks(struct drm_device *dev)
...
@@ -4585,7 +4585,9 @@ static void intel_update_watermarks(struct drm_device *dev)
static
inline
bool
intel_panel_use_ssc
(
struct
drm_i915_private
*
dev_priv
)
static
inline
bool
intel_panel_use_ssc
(
struct
drm_i915_private
*
dev_priv
)
{
{
return
dev_priv
->
lvds_use_ssc
&&
i915_panel_use_ssc
if
(
i915_panel_use_ssc
>=
0
)
return
i915_panel_use_ssc
!=
0
;
return
dev_priv
->
lvds_use_ssc
&&
!
(
dev_priv
->
quirks
&
QUIRK_LVDS_SSC_DISABLE
);
&&
!
(
dev_priv
->
quirks
&
QUIRK_LVDS_SSC_DISABLE
);
}
}
...
@@ -5108,36 +5110,52 @@ static int i9xx_crtc_mode_set(struct drm_crtc *crtc,
...
@@ -5108,36 +5110,52 @@ static int i9xx_crtc_mode_set(struct drm_crtc *crtc,
return
ret
;
return
ret
;
}
}
static
void
ironlake_update_pch_refclk
(
struct
drm_device
*
dev
)
/*
* Initialize reference clocks when the driver loads
*/
void
ironlake_init_pch_refclk
(
struct
drm_device
*
dev
)
{
{
struct
drm_i915_private
*
dev_priv
=
dev
->
dev_private
;
struct
drm_i915_private
*
dev_priv
=
dev
->
dev_private
;
struct
drm_mode_config
*
mode_config
=
&
dev
->
mode_config
;
struct
drm_mode_config
*
mode_config
=
&
dev
->
mode_config
;
struct
drm_crtc
*
crtc
;
struct
intel_encoder
*
encoder
;
struct
intel_encoder
*
encoder
;
struct
intel_encoder
*
has_edp_encoder
=
NULL
;
u32
temp
;
u32
temp
;
bool
has_lvds
=
false
;
bool
has_lvds
=
false
;
bool
has_cpu_edp
=
false
;
bool
has_pch_edp
=
false
;
bool
has_panel
=
false
;
bool
has_ck505
=
false
;
bool
can_ssc
=
false
;
/* We need to take the global config into account */
/* We need to take the global config into account */
list_for_each_entry
(
crtc
,
&
mode_config
->
crtc_list
,
head
)
{
list_for_each_entry
(
encoder
,
&
mode_config
->
encoder_list
,
if
(
!
crtc
->
enabled
)
base
.
head
)
{
continue
;
switch
(
encoder
->
type
)
{
case
INTEL_OUTPUT_LVDS
:
list_for_each_entry
(
encoder
,
&
mode_config
->
encoder_list
,
has_panel
=
true
;
base
.
head
)
{
has_lvds
=
true
;
if
(
encoder
->
base
.
crtc
!=
crtc
)
break
;
continue
;
case
INTEL_OUTPUT_EDP
:
has_panel
=
true
;
switch
(
encoder
->
type
)
{
if
(
intel_encoder_is_pch_edp
(
&
encoder
->
base
))
case
INTEL_OUTPUT_LVDS
:
has_pch_edp
=
true
;
has_lvds
=
true
;
else
case
INTEL_OUTPUT_EDP
:
has_cpu_edp
=
true
;
has_edp_encoder
=
encoder
;
break
;
break
;
}
}
}
}
}
if
(
HAS_PCH_IBX
(
dev
))
{
has_ck505
=
dev_priv
->
display_clock_mode
;
can_ssc
=
has_ck505
;
}
else
{
has_ck505
=
false
;
can_ssc
=
true
;
}
DRM_DEBUG_KMS
(
"has_panel %d has_lvds %d has_pch_edp %d has_cpu_edp %d has_ck505 %d
\n
"
,
has_panel
,
has_lvds
,
has_pch_edp
,
has_cpu_edp
,
has_ck505
);
/* Ironlake: try to setup display ref clock before DPLL
/* Ironlake: try to setup display ref clock before DPLL
* enabling. This is only under driver's control after
* enabling. This is only under driver's control after
* PCH B stepping, previous chipset stepping should be
* PCH B stepping, previous chipset stepping should be
...
@@ -5146,37 +5164,62 @@ static void ironlake_update_pch_refclk(struct drm_device *dev)
...
@@ -5146,37 +5164,62 @@ static void ironlake_update_pch_refclk(struct drm_device *dev)
temp
=
I915_READ
(
PCH_DREF_CONTROL
);
temp
=
I915_READ
(
PCH_DREF_CONTROL
);
/* Always enable nonspread source */
/* Always enable nonspread source */
temp
&=
~
DREF_NONSPREAD_SOURCE_MASK
;
temp
&=
~
DREF_NONSPREAD_SOURCE_MASK
;
temp
|=
DREF_NONSPREAD_SOURCE_ENABLE
;
temp
&=
~
DREF_SSC_SOURCE_MASK
;
temp
|=
DREF_SSC_SOURCE_ENABLE
;
I915_WRITE
(
PCH_DREF_CONTROL
,
temp
);
POSTING_READ
(
PCH_DREF_CONTROL
);
if
(
has_ck505
)
udelay
(
200
);
temp
|=
DREF_NONSPREAD_CK505_ENABLE
;
else
temp
|=
DREF_NONSPREAD_SOURCE_ENABLE
;
if
(
has_edp_encoder
)
{
if
(
has_panel
)
{
if
(
intel_panel_use_ssc
(
dev_priv
))
{
temp
&=
~
DREF_SSC_SOURCE_MASK
;
temp
|=
DREF_SSC1_ENABLE
;
temp
|=
DREF_SSC_SOURCE_ENABLE
;
I915_WRITE
(
PCH_DREF_CONTROL
,
temp
);
POSTING_READ
(
PCH_DREF_CONTROL
);
/* SSC must be turned on before enabling the CPU output */
udelay
(
200
);
if
(
intel_panel_use_ssc
(
dev_priv
)
&&
can_ssc
)
{
DRM_DEBUG_KMS
(
"Using SSC on panel
\n
"
);
temp
|=
DREF_SSC1_ENABLE
;
}
}
/* Get SSC going before enabling the outputs */
I915_WRITE
(
PCH_DREF_CONTROL
,
temp
);
POSTING_READ
(
PCH_DREF_CONTROL
);
udelay
(
200
);
temp
&=
~
DREF_CPU_SOURCE_OUTPUT_MASK
;
temp
&=
~
DREF_CPU_SOURCE_OUTPUT_MASK
;
/* Enable CPU source on CPU attached eDP */
/* Enable CPU source on CPU attached eDP */
if
(
!
intel_encoder_is_pch_edp
(
&
has_edp_encoder
->
base
))
{
if
(
has_cpu_edp
)
{
if
(
intel_panel_use_ssc
(
dev_priv
))
if
(
intel_panel_use_ssc
(
dev_priv
)
&&
can_ssc
)
{
DRM_DEBUG_KMS
(
"Using SSC on eDP
\n
"
);
temp
|=
DREF_CPU_SOURCE_OUTPUT_DOWNSPREAD
;
temp
|=
DREF_CPU_SOURCE_OUTPUT_DOWNSPREAD
;
}
else
else
temp
|=
DREF_CPU_SOURCE_OUTPUT_NONSPREAD
;
temp
|=
DREF_CPU_SOURCE_OUTPUT_NONSPREAD
;
}
else
{
}
else
/* Enable SSC on PCH eDP if needed */
temp
|=
DREF_CPU_SOURCE_OUTPUT_DISABLE
;
if
(
intel_panel_use_ssc
(
dev_priv
))
{
DRM_ERROR
(
"enabling SSC on PCH
\n
"
);
I915_WRITE
(
PCH_DREF_CONTROL
,
temp
);
temp
|=
DREF_SUPERSPREAD_SOURCE_ENABLE
;
POSTING_READ
(
PCH_DREF_CONTROL
);
}
udelay
(
200
);
}
}
else
{
DRM_DEBUG_KMS
(
"Disabling SSC entirely
\n
"
);
temp
&=
~
DREF_CPU_SOURCE_OUTPUT_MASK
;
/* Turn off CPU output */
temp
|=
DREF_CPU_SOURCE_OUTPUT_DISABLE
;
I915_WRITE
(
PCH_DREF_CONTROL
,
temp
);
POSTING_READ
(
PCH_DREF_CONTROL
);
udelay
(
200
);
/* Turn off the SSC source */
temp
&=
~
DREF_SSC_SOURCE_MASK
;
temp
|=
DREF_SSC_SOURCE_DISABLE
;
/* Turn off SSC1 */
temp
&=
~
DREF_SSC1_ENABLE
;
I915_WRITE
(
PCH_DREF_CONTROL
,
temp
);
I915_WRITE
(
PCH_DREF_CONTROL
,
temp
);
POSTING_READ
(
PCH_DREF_CONTROL
);
POSTING_READ
(
PCH_DREF_CONTROL
);
udelay
(
200
);
udelay
(
200
);
...
@@ -5242,16 +5285,10 @@ static int ironlake_crtc_mode_set(struct drm_crtc *crtc,
...
@@ -5242,16 +5285,10 @@ static int ironlake_crtc_mode_set(struct drm_crtc *crtc,
num_connectors
++
;
num_connectors
++
;
}
}
if
(
is_lvds
&&
intel_panel_use_ssc
(
dev_priv
)
&&
num_connectors
<
2
)
{
/*
refclk
=
dev_priv
->
lvds_ssc_freq
*
1000
;
* Every reference clock in a PCH system is 120MHz
DRM_DEBUG_KMS
(
"using SSC reference clock of %d MHz
\n
"
,
*/
refclk
/
1000
);
refclk
=
120000
;
}
else
{
refclk
=
96000
;
if
(
!
has_edp_encoder
||
intel_encoder_is_pch_edp
(
&
has_edp_encoder
->
base
))
refclk
=
120000
;
/* 120Mhz refclk */
}
/*
/*
* Returns a set of divisors for the desired target clock with the given
* Returns a set of divisors for the desired target clock with the given
...
@@ -5378,8 +5415,6 @@ static int ironlake_crtc_mode_set(struct drm_crtc *crtc,
...
@@ -5378,8 +5415,6 @@ static int ironlake_crtc_mode_set(struct drm_crtc *crtc,
ironlake_compute_m_n
(
intel_crtc
->
bpp
,
lane
,
target_clock
,
link_bw
,
ironlake_compute_m_n
(
intel_crtc
->
bpp
,
lane
,
target_clock
,
link_bw
,
&
m_n
);
&
m_n
);
ironlake_update_pch_refclk
(
dev
);
fp
=
clock
.
n
<<
16
|
clock
.
m1
<<
8
|
clock
.
m2
;
fp
=
clock
.
n
<<
16
|
clock
.
m1
<<
8
|
clock
.
m2
;
if
(
has_reduced_clock
)
if
(
has_reduced_clock
)
fp2
=
reduced_clock
.
n
<<
16
|
reduced_clock
.
m1
<<
8
|
fp2
=
reduced_clock
.
n
<<
16
|
reduced_clock
.
m1
<<
8
|
...
@@ -7376,6 +7411,9 @@ static void intel_setup_outputs(struct drm_device *dev)
...
@@ -7376,6 +7411,9 @@ static void intel_setup_outputs(struct drm_device *dev)
/* disable all the possible outputs/crtcs before entering KMS mode */
/* disable all the possible outputs/crtcs before entering KMS mode */
drm_helper_disable_unused_functions
(
dev
);
drm_helper_disable_unused_functions
(
dev
);
if
(
HAS_PCH_SPLIT
(
dev
))
ironlake_init_pch_refclk
(
dev
);
}
}
static
void
intel_user_framebuffer_destroy
(
struct
drm_framebuffer
*
fb
)
static
void
intel_user_framebuffer_destroy
(
struct
drm_framebuffer
*
fb
)
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment