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
85abf3ec
Commit
85abf3ec
authored
Apr 29, 2015
by
Takashi Iwai
Browse files
Options
Browse Files
Download
Plain Diff
Merge branch 'topic/hda' into for-next
parents
49c4a4c5
2bd1f73f
Changes
9
Hide whitespace changes
Inline
Side-by-side
Showing
9 changed files
with
99 additions
and
12 deletions
+99
-12
include/sound/hdaudio.h
include/sound/hdaudio.h
+4
-0
sound/hda/hdac_device.c
sound/hda/hdac_device.c
+15
-0
sound/pci/hda/hda_codec.c
sound/pci/hda/hda_codec.c
+4
-0
sound/pci/hda/hda_controller.c
sound/pci/hda/hda_controller.c
+11
-0
sound/pci/hda/hda_controller.h
sound/pci/hda/hda_controller.h
+2
-0
sound/pci/hda/hda_i915.c
sound/pci/hda/hda_i915.c
+14
-4
sound/pci/hda/hda_intel.c
sound/pci/hda/hda_intel.c
+38
-8
sound/pci/hda/hda_intel.h
sound/pci/hda/hda_intel.h
+2
-0
sound/pci/hda/patch_hdmi.c
sound/pci/hda/patch_hdmi.c
+9
-0
No files found.
include/sound/hdaudio.h
View file @
85abf3ec
...
...
@@ -74,6 +74,7 @@ struct hdac_device {
/* misc flags */
atomic_t
in_pm
;
/* suspend/resume being performed */
bool
link_power_control
:
1
;
/* sysfs */
struct
hdac_widget_tree
*
widgets
;
...
...
@@ -184,6 +185,8 @@ struct hdac_bus_ops {
/* get a response from the last command */
int
(
*
get_response
)(
struct
hdac_bus
*
bus
,
unsigned
int
addr
,
unsigned
int
*
res
);
/* control the link power */
int
(
*
link_power
)(
struct
hdac_bus
*
bus
,
bool
enable
);
};
/*
...
...
@@ -311,6 +314,7 @@ static inline void snd_hdac_codec_link_down(struct hdac_device *codec)
int
snd_hdac_bus_send_cmd
(
struct
hdac_bus
*
bus
,
unsigned
int
val
);
int
snd_hdac_bus_get_response
(
struct
hdac_bus
*
bus
,
unsigned
int
addr
,
unsigned
int
*
res
);
int
snd_hdac_link_power
(
struct
hdac_device
*
codec
,
bool
enable
);
bool
snd_hdac_bus_init_chip
(
struct
hdac_bus
*
bus
,
bool
full_reset
);
void
snd_hdac_bus_stop_chip
(
struct
hdac_bus
*
bus
);
...
...
sound/hda/hdac_device.c
View file @
85abf3ec
...
...
@@ -552,6 +552,21 @@ void snd_hdac_power_down_pm(struct hdac_device *codec)
EXPORT_SYMBOL_GPL
(
snd_hdac_power_down_pm
);
#endif
/*
* Enable/disable the link power for a codec.
*/
int
snd_hdac_link_power
(
struct
hdac_device
*
codec
,
bool
enable
)
{
if
(
!
codec
->
link_power_control
)
return
0
;
if
(
codec
->
bus
->
ops
->
link_power
)
return
codec
->
bus
->
ops
->
link_power
(
codec
->
bus
,
enable
);
else
return
-
EINVAL
;
}
EXPORT_SYMBOL_GPL
(
snd_hdac_link_power
);
/* codec vendor labels */
struct
hda_vendor_id
{
unsigned
int
id
;
...
...
sound/pci/hda/hda_codec.c
View file @
85abf3ec
...
...
@@ -858,6 +858,7 @@ void snd_hda_codec_register(struct hda_codec *codec)
return
;
if
(
device_is_registered
(
hda_codec_dev
(
codec
)))
{
snd_hda_register_beep_device
(
codec
);
snd_hdac_link_power
(
&
codec
->
core
,
true
);
pm_runtime_enable
(
hda_codec_dev
(
codec
));
/* it was powered up in snd_hda_codec_new(), now all done */
snd_hda_power_down
(
codec
);
...
...
@@ -884,6 +885,7 @@ static int snd_hda_codec_dev_free(struct snd_device *device)
struct
hda_codec
*
codec
=
device
->
device_data
;
codec
->
in_freeing
=
1
;
snd_hdac_link_power
(
&
codec
->
core
,
false
);
snd_hdac_device_unregister
(
&
codec
->
core
);
put_device
(
hda_codec_dev
(
codec
));
return
0
;
...
...
@@ -3106,6 +3108,7 @@ static int hda_codec_runtime_suspend(struct device *dev)
if
(
codec_has_clkstop
(
codec
)
&&
codec_has_epss
(
codec
)
&&
(
state
&
AC_PWRST_CLK_STOP_OK
))
snd_hdac_codec_link_down
(
&
codec
->
core
);
snd_hdac_link_power
(
&
codec
->
core
,
false
);
return
0
;
}
...
...
@@ -3113,6 +3116,7 @@ static int hda_codec_runtime_resume(struct device *dev)
{
struct
hda_codec
*
codec
=
dev_to_hda_codec
(
dev
);
snd_hdac_link_power
(
&
codec
->
core
,
true
);
snd_hdac_codec_link_up
(
&
codec
->
core
);
hda_call_codec_resume
(
codec
);
pm_runtime_mark_last_busy
(
dev
);
...
...
sound/pci/hda/hda_controller.c
View file @
85abf3ec
...
...
@@ -775,9 +775,20 @@ static int azx_get_response(struct hdac_bus *bus, unsigned int addr,
return
azx_rirb_get_response
(
bus
,
addr
,
res
);
}
static
int
azx_link_power
(
struct
hdac_bus
*
bus
,
bool
enable
)
{
struct
azx
*
chip
=
bus_to_azx
(
bus
);
if
(
chip
->
ops
->
link_power
)
return
chip
->
ops
->
link_power
(
chip
,
enable
);
else
return
-
EINVAL
;
}
static
const
struct
hdac_bus_ops
bus_core_ops
=
{
.
command
=
azx_send_cmd
,
.
get_response
=
azx_get_response
,
.
link_power
=
azx_link_power
,
};
#ifdef CONFIG_SND_HDA_DSP_LOADER
...
...
sound/pci/hda/hda_controller.h
View file @
85abf3ec
...
...
@@ -89,6 +89,8 @@ struct hda_controller_ops {
struct
vm_area_struct
*
area
);
/* Check if current position is acceptable */
int
(
*
position_check
)(
struct
azx
*
chip
,
struct
azx_dev
*
azx_dev
);
/* enable/disable the link power */
int
(
*
link_power
)(
struct
azx
*
chip
,
bool
enable
);
};
struct
azx_pcm
{
...
...
sound/pci/hda/hda_i915.c
View file @
85abf3ec
...
...
@@ -42,10 +42,15 @@ int hda_display_power(struct hda_intel *hda, bool enable)
dev_dbg
(
&
hda
->
chip
.
pci
->
dev
,
"display power %s
\n
"
,
enable
?
"enable"
:
"disable"
);
if
(
enable
)
acomp
->
ops
->
get_power
(
acomp
->
dev
);
else
acomp
->
ops
->
put_power
(
acomp
->
dev
);
if
(
enable
)
{
if
(
!
hda
->
i915_power_refcount
++
)
acomp
->
ops
->
get_power
(
acomp
->
dev
);
}
else
{
WARN_ON
(
!
hda
->
i915_power_refcount
);
if
(
!--
hda
->
i915_power_refcount
)
acomp
->
ops
->
put_power
(
acomp
->
dev
);
}
return
0
;
}
...
...
@@ -189,6 +194,11 @@ int hda_i915_init(struct hda_intel *hda)
int
hda_i915_exit
(
struct
hda_intel
*
hda
)
{
struct
device
*
dev
=
&
hda
->
chip
.
pci
->
dev
;
struct
i915_audio_component
*
acomp
=
&
hda
->
audio_component
;
WARN_ON
(
hda
->
i915_power_refcount
);
if
(
hda
->
i915_power_refcount
>
0
&&
acomp
->
ops
)
acomp
->
ops
->
put_power
(
acomp
->
dev
);
component_master_del
(
dev
,
&
hda_component_master_ops
);
...
...
sound/pci/hda/hda_intel.c
View file @
85abf3ec
...
...
@@ -543,6 +543,14 @@ static int azx_position_check(struct azx *chip, struct azx_dev *azx_dev)
return
0
;
}
/* Enable/disable i915 display power for the link */
static
int
azx_intel_link_power
(
struct
azx
*
chip
,
bool
enable
)
{
struct
hda_intel
*
hda
=
container_of
(
chip
,
struct
hda_intel
,
chip
);
return
hda_display_power
(
hda
,
enable
);
}
/*
* Check whether the current DMA position is acceptable for updating
* periods. Returns non-zero if it's OK.
...
...
@@ -809,7 +817,8 @@ static int azx_suspend(struct device *dev)
if
(
chip
->
msi
)
pci_disable_msi
(
chip
->
pci
);
if
(
chip
->
driver_caps
&
AZX_DCAPS_I915_POWERWELL
)
if
(
chip
->
driver_caps
&
AZX_DCAPS_I915_POWERWELL
&&
hda
->
need_i915_power
)
hda_display_power
(
hda
,
false
);
return
0
;
}
...
...
@@ -829,7 +838,8 @@ static int azx_resume(struct device *dev)
if
(
chip
->
disabled
||
hda
->
init_failed
)
return
0
;
if
(
chip
->
driver_caps
&
AZX_DCAPS_I915_POWERWELL
)
{
if
(
chip
->
driver_caps
&
AZX_DCAPS_I915_POWERWELL
&&
hda
->
need_i915_power
)
{
hda_display_power
(
hda
,
true
);
haswell_set_bclk
(
hda
);
}
...
...
@@ -872,7 +882,8 @@ static int azx_runtime_suspend(struct device *dev)
azx_stop_chip
(
chip
);
azx_enter_link_reset
(
chip
);
azx_clear_irq_pending
(
chip
);
if
(
chip
->
driver_caps
&
AZX_DCAPS_I915_POWERWELL
)
if
(
chip
->
driver_caps
&
AZX_DCAPS_I915_POWERWELL
&&
hda
->
need_i915_power
)
hda_display_power
(
hda
,
false
);
return
0
;
...
...
@@ -897,7 +908,8 @@ static int azx_runtime_resume(struct device *dev)
if
(
!
azx_has_pm_runtime
(
chip
))
return
0
;
if
(
chip
->
driver_caps
&
AZX_DCAPS_I915_POWERWELL
)
{
if
(
chip
->
driver_caps
&
AZX_DCAPS_I915_POWERWELL
&&
hda
->
need_i915_power
)
{
hda_display_power
(
hda
,
true
);
haswell_set_bclk
(
hda
);
}
...
...
@@ -1118,7 +1130,8 @@ static int azx_free(struct azx *chip)
release_firmware
(
chip
->
fw
);
#endif
if
(
chip
->
driver_caps
&
AZX_DCAPS_I915_POWERWELL
)
{
hda_display_power
(
hda
,
false
);
if
(
hda
->
need_i915_power
)
hda_display_power
(
hda
,
false
);
hda_i915_exit
(
hda
);
}
kfree
(
hda
);
...
...
@@ -1789,6 +1802,7 @@ static const struct hda_controller_ops pci_hda_ops = {
.
substream_free_pages
=
substream_free_pages
,
.
pcm_mmap_prepare
=
pcm_mmap_prepare
,
.
position_check
=
azx_position_check
,
.
link_power
=
azx_intel_link_power
,
};
static
int
azx_probe
(
struct
pci_dev
*
pci
,
...
...
@@ -1882,17 +1896,28 @@ static int azx_probe_continue(struct azx *chip)
int
err
;
hda
->
probe_continued
=
1
;
/* Request power well for Haswell HDA controller and codec */
/* Request display power well for the HDA controller or codec. For
* Haswell/Broadwell, both the display HDA controller and codec need
* this power. For other platforms, like Baytrail/Braswell, only the
* display codec needs the power and it can be released after probe.
*/
if
(
chip
->
driver_caps
&
AZX_DCAPS_I915_POWERWELL
)
{
/* Baytral/Braswell controllers don't need this power */
if
(
pci
->
device
!=
0x0f04
&&
pci
->
device
!=
0x2284
)
hda
->
need_i915_power
=
1
;
#ifdef CONFIG_SND_HDA_I915
err
=
hda_i915_init
(
hda
);
if
(
err
<
0
)
goto
out_free
;
goto
i915_power_fail
;
err
=
hda_display_power
(
hda
,
true
);
if
(
err
<
0
)
{
dev_err
(
chip
->
card
->
dev
,
"Cannot turn on display power on i915
\n
"
);
goto
out_free
;
goto
i915_power_fail
;
}
#endif
}
...
...
@@ -1939,6 +1964,11 @@ static int azx_probe_continue(struct azx *chip)
pm_runtime_put_noidle
(
&
pci
->
dev
);
out_free:
if
(
chip
->
driver_caps
&
AZX_DCAPS_I915_POWERWELL
&&
!
hda
->
need_i915_power
)
hda_display_power
(
hda
,
false
);
i915_power_fail:
if
(
err
<
0
)
hda
->
init_failed
=
1
;
complete_all
(
&
hda
->
probe_wait
);
...
...
sound/pci/hda/hda_intel.h
View file @
85abf3ec
...
...
@@ -45,7 +45,9 @@ struct hda_intel {
struct
dev_pm_domain
hdmi_pm_domain
;
/* i915 component interface */
bool
need_i915_power
:
1
;
/* the hda controller needs i915 power */
struct
i915_audio_component
audio_component
;
int
i915_power_refcount
;
};
#ifdef CONFIG_SND_HDA_I915
...
...
sound/pci/hda/patch_hdmi.c
View file @
85abf3ec
...
...
@@ -2335,6 +2335,15 @@ static int patch_generic_hdmi(struct hda_codec *codec)
intel_haswell_fixup_enable_dp12
(
codec
);
}
/* For Valleyview/Cherryview, only the display codec is in the display
* power well and can use link_power ops to request/release the power.
* For Haswell/Broadwell, the controller is also in the power well and
* can cover the codec power request, and so need not set this flag.
* For previous platforms, there is no such power well feature.
*/
if
(
is_valleyview_plus
(
codec
))
codec
->
core
.
link_power_control
=
1
;
if
(
is_haswell_plus
(
codec
)
||
is_valleyview_plus
(
codec
))
codec
->
depop_delay
=
0
;
...
...
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