Skip to content
体验新版
项目
组织
正在加载...
登录
切换导航
打开侧边栏
OpenHarmony
kernel_linux
提交
c0c0d9ee
K
kernel_linux
项目概览
OpenHarmony
/
kernel_linux
上一次同步 大约 4 年
通知
14
Star
8
Fork
2
代码
文件
提交
分支
Tags
贡献者
分支图
Diff
Issue
0
列表
看板
标记
里程碑
合并请求
0
DevOps
流水线
流水线任务
计划
Wiki
0
Wiki
分析
仓库
DevOps
项目成员
Pages
K
kernel_linux
项目概览
项目概览
详情
发布
仓库
仓库
文件
提交
分支
标签
贡献者
分支图
比较
Issue
0
Issue
0
列表
看板
标记
里程碑
合并请求
0
合并请求
0
Pages
DevOps
DevOps
流水线
流水线任务
计划
分析
分析
仓库分析
DevOps
Wiki
0
Wiki
成员
成员
收起侧边栏
关闭侧边栏
动态
分支图
创建新Issue
流水线任务
提交
Issue看板
提交
c0c0d9ee
编写于
12月 11, 2013
作者:
R
Rob Clark
浏览文件
操作
浏览文件
下载
电子邮件补丁
差异文件
drm/msm: hdmi audio support
Signed-off-by:
N
Rob Clark
<
robdclark@gmail.com
>
上级
c32fc9c8
变更
5
隐藏空白更改
内联
并排
Showing
5 changed file
with
317 addition
and
16 deletion
+317
-16
drivers/gpu/drm/msm/Makefile
drivers/gpu/drm/msm/Makefile
+1
-0
drivers/gpu/drm/msm/hdmi/hdmi.c
drivers/gpu/drm/msm/hdmi/hdmi.c
+7
-1
drivers/gpu/drm/msm/hdmi/hdmi.h
drivers/gpu/drm/msm/hdmi/hdmi.h
+25
-0
drivers/gpu/drm/msm/hdmi/hdmi_audio.c
drivers/gpu/drm/msm/hdmi/hdmi_audio.c
+273
-0
drivers/gpu/drm/msm/hdmi/hdmi_bridge.c
drivers/gpu/drm/msm/hdmi/hdmi_bridge.c
+11
-15
未找到文件。
drivers/gpu/drm/msm/Makefile
浏览文件 @
c0c0d9ee
...
@@ -7,6 +7,7 @@ msm-y := \
...
@@ -7,6 +7,7 @@ msm-y := \
adreno/adreno_gpu.o
\
adreno/adreno_gpu.o
\
adreno/a3xx_gpu.o
\
adreno/a3xx_gpu.o
\
hdmi/hdmi.o
\
hdmi/hdmi.o
\
hdmi/hdmi_audio.o
\
hdmi/hdmi_bridge.o
\
hdmi/hdmi_bridge.o
\
hdmi/hdmi_connector.o
\
hdmi/hdmi_connector.o
\
hdmi/hdmi_i2c.o
\
hdmi/hdmi_i2c.o
\
...
...
drivers/gpu/drm/msm/hdmi/hdmi.c
浏览文件 @
c0c0d9ee
...
@@ -67,6 +67,8 @@ void hdmi_destroy(struct kref *kref)
...
@@ -67,6 +67,8 @@ void hdmi_destroy(struct kref *kref)
if
(
hdmi
->
i2c
)
if
(
hdmi
->
i2c
)
hdmi_i2c_destroy
(
hdmi
->
i2c
);
hdmi_i2c_destroy
(
hdmi
->
i2c
);
platform_set_drvdata
(
hdmi
->
pdev
,
NULL
);
put_device
(
&
hdmi
->
pdev
->
dev
);
put_device
(
&
hdmi
->
pdev
->
dev
);
}
}
...
@@ -102,6 +104,8 @@ struct hdmi *hdmi_init(struct drm_device *dev, struct drm_encoder *encoder)
...
@@ -102,6 +104,8 @@ struct hdmi *hdmi_init(struct drm_device *dev, struct drm_encoder *encoder)
hdmi
->
config
=
config
;
hdmi
->
config
=
config
;
hdmi
->
encoder
=
encoder
;
hdmi
->
encoder
=
encoder
;
hdmi_audio_infoframe_init
(
&
hdmi
->
audio
.
infoframe
);
/* not sure about which phy maps to which msm.. probably I miss some */
/* not sure about which phy maps to which msm.. probably I miss some */
if
(
config
->
phy_init
)
if
(
config
->
phy_init
)
hdmi
->
phy
=
config
->
phy_init
(
hdmi
);
hdmi
->
phy
=
config
->
phy_init
(
hdmi
);
...
@@ -228,6 +232,8 @@ struct hdmi *hdmi_init(struct drm_device *dev, struct drm_encoder *encoder)
...
@@ -228,6 +232,8 @@ struct hdmi *hdmi_init(struct drm_device *dev, struct drm_encoder *encoder)
priv
->
bridges
[
priv
->
num_bridges
++
]
=
hdmi
->
bridge
;
priv
->
bridges
[
priv
->
num_bridges
++
]
=
hdmi
->
bridge
;
priv
->
connectors
[
priv
->
num_connectors
++
]
=
hdmi
->
connector
;
priv
->
connectors
[
priv
->
num_connectors
++
]
=
hdmi
->
connector
;
platform_set_drvdata
(
pdev
,
hdmi
);
return
hdmi
;
return
hdmi
;
fail:
fail:
...
@@ -305,7 +311,7 @@ static int hdmi_dev_probe(struct platform_device *pdev)
...
@@ -305,7 +311,7 @@ static int hdmi_dev_probe(struct platform_device *pdev)
config
.
ddc_data_gpio
=
71
;
config
.
ddc_data_gpio
=
71
;
config
.
hpd_gpio
=
72
;
config
.
hpd_gpio
=
72
;
config
.
mux_en_gpio
=
-
1
;
config
.
mux_en_gpio
=
-
1
;
config
.
mux_sel_gpio
=
13
+
NR_GPIO_IRQS
;
config
.
mux_sel_gpio
=
-
1
;
}
else
if
(
cpu_is_msm8960
()
||
cpu_is_msm8960ab
())
{
}
else
if
(
cpu_is_msm8960
()
||
cpu_is_msm8960ab
())
{
static
const
char
*
hpd_reg_names
[]
=
{
"8921_hdmi_mvs"
};
static
const
char
*
hpd_reg_names
[]
=
{
"8921_hdmi_mvs"
};
config
.
phy_init
=
hdmi_phy_8960_init
;
config
.
phy_init
=
hdmi_phy_8960_init
;
...
...
drivers/gpu/drm/msm/hdmi/hdmi.h
浏览文件 @
c0c0d9ee
...
@@ -22,6 +22,7 @@
...
@@ -22,6 +22,7 @@
#include <linux/clk.h>
#include <linux/clk.h>
#include <linux/platform_device.h>
#include <linux/platform_device.h>
#include <linux/regulator/consumer.h>
#include <linux/regulator/consumer.h>
#include <linux/hdmi.h>
#include "msm_drv.h"
#include "msm_drv.h"
#include "hdmi.xml.h"
#include "hdmi.xml.h"
...
@@ -30,6 +31,12 @@
...
@@ -30,6 +31,12 @@
struct
hdmi_phy
;
struct
hdmi_phy
;
struct
hdmi_platform_config
;
struct
hdmi_platform_config
;
struct
hdmi_audio
{
bool
enabled
;
struct
hdmi_audio_infoframe
infoframe
;
int
rate
;
};
struct
hdmi
{
struct
hdmi
{
struct
kref
refcount
;
struct
kref
refcount
;
...
@@ -38,6 +45,13 @@ struct hdmi {
...
@@ -38,6 +45,13 @@ struct hdmi {
const
struct
hdmi_platform_config
*
config
;
const
struct
hdmi_platform_config
*
config
;
/* audio state: */
struct
hdmi_audio
audio
;
/* video state: */
bool
power_on
;
unsigned
long
int
pixclock
;
void
__iomem
*
mmio
;
void
__iomem
*
mmio
;
struct
regulator
*
hpd_regs
[
2
];
struct
regulator
*
hpd_regs
[
2
];
...
@@ -131,6 +145,17 @@ struct hdmi_phy *hdmi_phy_8960_init(struct hdmi *hdmi);
...
@@ -131,6 +145,17 @@ struct hdmi_phy *hdmi_phy_8960_init(struct hdmi *hdmi);
struct
hdmi_phy
*
hdmi_phy_8x60_init
(
struct
hdmi
*
hdmi
);
struct
hdmi_phy
*
hdmi_phy_8x60_init
(
struct
hdmi
*
hdmi
);
struct
hdmi_phy
*
hdmi_phy_8x74_init
(
struct
hdmi
*
hdmi
);
struct
hdmi_phy
*
hdmi_phy_8x74_init
(
struct
hdmi
*
hdmi
);
/*
* audio:
*/
int
hdmi_audio_update
(
struct
hdmi
*
hdmi
);
int
hdmi_audio_info_setup
(
struct
hdmi
*
hdmi
,
bool
enabled
,
uint32_t
num_of_channels
,
uint32_t
channel_allocation
,
uint32_t
level_shift
,
bool
down_mix
);
void
hdmi_audio_set_sample_rate
(
struct
hdmi
*
hdmi
,
int
rate
);
/*
/*
* hdmi bridge:
* hdmi bridge:
*/
*/
...
...
drivers/gpu/drm/msm/hdmi/hdmi_audio.c
0 → 100644
浏览文件 @
c0c0d9ee
/*
* Copyright (C) 2013 Red Hat
* Author: Rob Clark <robdclark@gmail.com>
*
* This program is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 as published by
* the Free Software Foundation.
*
* This program is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
* more details.
*
* You should have received a copy of the GNU General Public License along with
* this program. If not, see <http://www.gnu.org/licenses/>.
*/
#include <linux/hdmi.h>
#include "hdmi.h"
/* Supported HDMI Audio channels */
#define MSM_HDMI_AUDIO_CHANNEL_2 0
#define MSM_HDMI_AUDIO_CHANNEL_4 1
#define MSM_HDMI_AUDIO_CHANNEL_6 2
#define MSM_HDMI_AUDIO_CHANNEL_8 3
/* maps MSM_HDMI_AUDIO_CHANNEL_n consts used by audio driver to # of channels: */
static
int
nchannels
[]
=
{
2
,
4
,
6
,
8
};
/* Supported HDMI Audio sample rates */
#define MSM_HDMI_SAMPLE_RATE_32KHZ 0
#define MSM_HDMI_SAMPLE_RATE_44_1KHZ 1
#define MSM_HDMI_SAMPLE_RATE_48KHZ 2
#define MSM_HDMI_SAMPLE_RATE_88_2KHZ 3
#define MSM_HDMI_SAMPLE_RATE_96KHZ 4
#define MSM_HDMI_SAMPLE_RATE_176_4KHZ 5
#define MSM_HDMI_SAMPLE_RATE_192KHZ 6
#define MSM_HDMI_SAMPLE_RATE_MAX 7
struct
hdmi_msm_audio_acr
{
uint32_t
n
;
/* N parameter for clock regeneration */
uint32_t
cts
;
/* CTS parameter for clock regeneration */
};
struct
hdmi_msm_audio_arcs
{
unsigned
long
int
pixclock
;
struct
hdmi_msm_audio_acr
lut
[
MSM_HDMI_SAMPLE_RATE_MAX
];
};
#define HDMI_MSM_AUDIO_ARCS(pclk, ...) { (1000 * (pclk)), __VA_ARGS__ }
/* Audio constants lookup table for hdmi_msm_audio_acr_setup */
/* Valid Pixel-Clock rates: 25.2MHz, 27MHz, 27.03MHz, 74.25MHz, 148.5MHz */
static
const
struct
hdmi_msm_audio_arcs
acr_lut
[]
=
{
/* 25.200MHz */
HDMI_MSM_AUDIO_ARCS
(
25200
,
{
{
4096
,
25200
},
{
6272
,
28000
},
{
6144
,
25200
},
{
12544
,
28000
},
{
12288
,
25200
},
{
25088
,
28000
},
{
24576
,
25200
}
}),
/* 27.000MHz */
HDMI_MSM_AUDIO_ARCS
(
27000
,
{
{
4096
,
27000
},
{
6272
,
30000
},
{
6144
,
27000
},
{
12544
,
30000
},
{
12288
,
27000
},
{
25088
,
30000
},
{
24576
,
27000
}
}),
/* 27.027MHz */
HDMI_MSM_AUDIO_ARCS
(
27030
,
{
{
4096
,
27027
},
{
6272
,
30030
},
{
6144
,
27027
},
{
12544
,
30030
},
{
12288
,
27027
},
{
25088
,
30030
},
{
24576
,
27027
}
}),
/* 74.250MHz */
HDMI_MSM_AUDIO_ARCS
(
74250
,
{
{
4096
,
74250
},
{
6272
,
82500
},
{
6144
,
74250
},
{
12544
,
82500
},
{
12288
,
74250
},
{
25088
,
82500
},
{
24576
,
74250
}
}),
/* 148.500MHz */
HDMI_MSM_AUDIO_ARCS
(
148500
,
{
{
4096
,
148500
},
{
6272
,
165000
},
{
6144
,
148500
},
{
12544
,
165000
},
{
12288
,
148500
},
{
25088
,
165000
},
{
24576
,
148500
}
}),
};
static
const
struct
hdmi_msm_audio_arcs
*
get_arcs
(
unsigned
long
int
pixclock
)
{
int
i
;
for
(
i
=
0
;
i
<
ARRAY_SIZE
(
acr_lut
);
i
++
)
{
const
struct
hdmi_msm_audio_arcs
*
arcs
=
&
acr_lut
[
i
];
if
(
arcs
->
pixclock
==
pixclock
)
return
arcs
;
}
return
NULL
;
}
int
hdmi_audio_update
(
struct
hdmi
*
hdmi
)
{
struct
hdmi_audio
*
audio
=
&
hdmi
->
audio
;
struct
hdmi_audio_infoframe
*
info
=
&
audio
->
infoframe
;
const
struct
hdmi_msm_audio_arcs
*
arcs
=
NULL
;
bool
enabled
=
audio
->
enabled
;
uint32_t
acr_pkt_ctrl
,
vbi_pkt_ctrl
,
aud_pkt_ctrl
;
uint32_t
infofrm_ctrl
,
audio_config
;
DBG
(
"audio: enabled=%d, channels=%d, channel_allocation=0x%x, "
"level_shift_value=%d, downmix_inhibit=%d, rate=%d"
,
audio
->
enabled
,
info
->
channels
,
info
->
channel_allocation
,
info
->
level_shift_value
,
info
->
downmix_inhibit
,
audio
->
rate
);
DBG
(
"video: power_on=%d, pixclock=%lu"
,
hdmi
->
power_on
,
hdmi
->
pixclock
);
if
(
enabled
&&
!
(
hdmi
->
power_on
&&
hdmi
->
pixclock
))
{
DBG
(
"disabling audio: no video"
);
enabled
=
false
;
}
if
(
enabled
)
{
arcs
=
get_arcs
(
hdmi
->
pixclock
);
if
(
!
arcs
)
{
DBG
(
"disabling audio: unsupported pixclock: %lu"
,
hdmi
->
pixclock
);
enabled
=
false
;
}
}
/* Read first before writing */
acr_pkt_ctrl
=
hdmi_read
(
hdmi
,
REG_HDMI_ACR_PKT_CTRL
);
vbi_pkt_ctrl
=
hdmi_read
(
hdmi
,
REG_HDMI_VBI_PKT_CTRL
);
aud_pkt_ctrl
=
hdmi_read
(
hdmi
,
REG_HDMI_AUDIO_PKT_CTRL1
);
infofrm_ctrl
=
hdmi_read
(
hdmi
,
REG_HDMI_INFOFRAME_CTRL0
);
audio_config
=
hdmi_read
(
hdmi
,
REG_HDMI_AUDIO_CFG
);
/* Clear N/CTS selection bits */
acr_pkt_ctrl
&=
~
HDMI_ACR_PKT_CTRL_SELECT__MASK
;
if
(
enabled
)
{
uint32_t
n
,
cts
,
multiplier
;
enum
hdmi_acr_cts
select
;
uint8_t
buf
[
14
];
n
=
arcs
->
lut
[
audio
->
rate
].
n
;
cts
=
arcs
->
lut
[
audio
->
rate
].
cts
;
if
((
MSM_HDMI_SAMPLE_RATE_192KHZ
==
audio
->
rate
)
||
(
MSM_HDMI_SAMPLE_RATE_176_4KHZ
==
audio
->
rate
))
{
multiplier
=
4
;
n
>>=
2
;
/* divide N by 4 and use multiplier */
}
else
if
((
MSM_HDMI_SAMPLE_RATE_96KHZ
==
audio
->
rate
)
||
(
MSM_HDMI_SAMPLE_RATE_88_2KHZ
==
audio
->
rate
))
{
multiplier
=
2
;
n
>>=
1
;
/* divide N by 2 and use multiplier */
}
else
{
multiplier
=
1
;
}
DBG
(
"n=%u, cts=%u, multiplier=%u"
,
n
,
cts
,
multiplier
);
acr_pkt_ctrl
|=
HDMI_ACR_PKT_CTRL_SOURCE
;
acr_pkt_ctrl
|=
HDMI_ACR_PKT_CTRL_AUDIO_PRIORITY
;
acr_pkt_ctrl
|=
HDMI_ACR_PKT_CTRL_N_MULTIPLIER
(
multiplier
);
if
((
MSM_HDMI_SAMPLE_RATE_48KHZ
==
audio
->
rate
)
||
(
MSM_HDMI_SAMPLE_RATE_96KHZ
==
audio
->
rate
)
||
(
MSM_HDMI_SAMPLE_RATE_192KHZ
==
audio
->
rate
))
select
=
ACR_48
;
else
if
((
MSM_HDMI_SAMPLE_RATE_44_1KHZ
==
audio
->
rate
)
||
(
MSM_HDMI_SAMPLE_RATE_88_2KHZ
==
audio
->
rate
)
||
(
MSM_HDMI_SAMPLE_RATE_176_4KHZ
==
audio
->
rate
))
select
=
ACR_44
;
else
/* default to 32k */
select
=
ACR_32
;
acr_pkt_ctrl
|=
HDMI_ACR_PKT_CTRL_SELECT
(
select
);
hdmi_write
(
hdmi
,
REG_HDMI_ACR_0
(
select
-
1
),
HDMI_ACR_0_CTS
(
cts
));
hdmi_write
(
hdmi
,
REG_HDMI_ACR_1
(
select
-
1
),
HDMI_ACR_1_N
(
n
));
hdmi_write
(
hdmi
,
REG_HDMI_AUDIO_PKT_CTRL2
,
COND
(
info
->
channels
!=
2
,
HDMI_AUDIO_PKT_CTRL2_LAYOUT
)
|
HDMI_AUDIO_PKT_CTRL2_OVERRIDE
);
acr_pkt_ctrl
|=
HDMI_ACR_PKT_CTRL_CONT
;
acr_pkt_ctrl
|=
HDMI_ACR_PKT_CTRL_SEND
;
/* configure infoframe: */
hdmi_audio_infoframe_pack
(
info
,
buf
,
sizeof
(
buf
));
hdmi_write
(
hdmi
,
REG_HDMI_AUDIO_INFO0
,
(
buf
[
3
]
<<
0
)
||
(
buf
[
4
]
<<
8
)
||
(
buf
[
5
]
<<
16
)
||
(
buf
[
6
]
<<
24
));
hdmi_write
(
hdmi
,
REG_HDMI_AUDIO_INFO1
,
(
buf
[
7
]
<<
0
)
||
(
buf
[
8
]
<<
8
));
hdmi_write
(
hdmi
,
REG_HDMI_GC
,
0
);
vbi_pkt_ctrl
|=
HDMI_VBI_PKT_CTRL_GC_ENABLE
;
vbi_pkt_ctrl
|=
HDMI_VBI_PKT_CTRL_GC_EVERY_FRAME
;
aud_pkt_ctrl
|=
HDMI_AUDIO_PKT_CTRL1_AUDIO_SAMPLE_SEND
;
infofrm_ctrl
|=
HDMI_INFOFRAME_CTRL0_AUDIO_INFO_SEND
;
infofrm_ctrl
|=
HDMI_INFOFRAME_CTRL0_AUDIO_INFO_CONT
;
infofrm_ctrl
|=
HDMI_INFOFRAME_CTRL0_AUDIO_INFO_SOURCE
;
infofrm_ctrl
|=
HDMI_INFOFRAME_CTRL0_AUDIO_INFO_UPDATE
;
audio_config
&=
~
HDMI_AUDIO_CFG_FIFO_WATERMARK__MASK
;
audio_config
|=
HDMI_AUDIO_CFG_FIFO_WATERMARK
(
4
);
audio_config
|=
HDMI_AUDIO_CFG_ENGINE_ENABLE
;
}
else
{
hdmi_write
(
hdmi
,
REG_HDMI_GC
,
HDMI_GC_MUTE
);
acr_pkt_ctrl
&=
~
HDMI_ACR_PKT_CTRL_CONT
;
acr_pkt_ctrl
&=
~
HDMI_ACR_PKT_CTRL_SEND
;
vbi_pkt_ctrl
&=
~
HDMI_VBI_PKT_CTRL_GC_ENABLE
;
vbi_pkt_ctrl
&=
~
HDMI_VBI_PKT_CTRL_GC_EVERY_FRAME
;
aud_pkt_ctrl
&=
~
HDMI_AUDIO_PKT_CTRL1_AUDIO_SAMPLE_SEND
;
infofrm_ctrl
&=
~
HDMI_INFOFRAME_CTRL0_AUDIO_INFO_SEND
;
infofrm_ctrl
&=
~
HDMI_INFOFRAME_CTRL0_AUDIO_INFO_CONT
;
infofrm_ctrl
&=
~
HDMI_INFOFRAME_CTRL0_AUDIO_INFO_SOURCE
;
infofrm_ctrl
&=
~
HDMI_INFOFRAME_CTRL0_AUDIO_INFO_UPDATE
;
audio_config
&=
~
HDMI_AUDIO_CFG_ENGINE_ENABLE
;
}
hdmi_write
(
hdmi
,
REG_HDMI_ACR_PKT_CTRL
,
acr_pkt_ctrl
);
hdmi_write
(
hdmi
,
REG_HDMI_VBI_PKT_CTRL
,
vbi_pkt_ctrl
);
hdmi_write
(
hdmi
,
REG_HDMI_AUDIO_PKT_CTRL1
,
aud_pkt_ctrl
);
hdmi_write
(
hdmi
,
REG_HDMI_INFOFRAME_CTRL0
,
infofrm_ctrl
);
hdmi_write
(
hdmi
,
REG_HDMI_AUD_INT
,
COND
(
enabled
,
HDMI_AUD_INT_AUD_FIFO_URUN_INT
)
|
COND
(
enabled
,
HDMI_AUD_INT_AUD_SAM_DROP_INT
));
hdmi_write
(
hdmi
,
REG_HDMI_AUDIO_CFG
,
audio_config
);
DBG
(
"audio %sabled"
,
enabled
?
"en"
:
"dis"
);
return
0
;
}
int
hdmi_audio_info_setup
(
struct
hdmi
*
hdmi
,
bool
enabled
,
uint32_t
num_of_channels
,
uint32_t
channel_allocation
,
uint32_t
level_shift
,
bool
down_mix
)
{
struct
hdmi_audio
*
audio
;
if
(
!
hdmi
)
return
-
ENXIO
;
audio
=
&
hdmi
->
audio
;
if
(
num_of_channels
>=
ARRAY_SIZE
(
nchannels
))
return
-
EINVAL
;
audio
->
enabled
=
enabled
;
audio
->
infoframe
.
channels
=
nchannels
[
num_of_channels
];
audio
->
infoframe
.
channel_allocation
=
channel_allocation
;
audio
->
infoframe
.
level_shift_value
=
level_shift
;
audio
->
infoframe
.
downmix_inhibit
=
down_mix
;
return
hdmi_audio_update
(
hdmi
);
}
void
hdmi_audio_set_sample_rate
(
struct
hdmi
*
hdmi
,
int
rate
)
{
struct
hdmi_audio
*
audio
;
if
(
!
hdmi
)
return
;
audio
=
&
hdmi
->
audio
;
if
((
rate
<
0
)
||
(
rate
>=
MSM_HDMI_SAMPLE_RATE_MAX
))
return
;
audio
->
rate
=
rate
;
hdmi_audio_update
(
hdmi
);
}
drivers/gpu/drm/msm/hdmi/hdmi_bridge.c
浏览文件 @
c0c0d9ee
...
@@ -19,11 +19,7 @@
...
@@ -19,11 +19,7 @@
struct
hdmi_bridge
{
struct
hdmi_bridge
{
struct
drm_bridge
base
;
struct
drm_bridge
base
;
struct
hdmi
*
hdmi
;
struct
hdmi
*
hdmi
;
bool
power_on
;
unsigned
long
int
pixclock
;
};
};
#define to_hdmi_bridge(x) container_of(x, struct hdmi_bridge, base)
#define to_hdmi_bridge(x) container_of(x, struct hdmi_bridge, base)
...
@@ -52,8 +48,8 @@ static void power_on(struct drm_bridge *bridge)
...
@@ -52,8 +48,8 @@ static void power_on(struct drm_bridge *bridge)
}
}
if
(
config
->
pwr_clk_cnt
>
0
)
{
if
(
config
->
pwr_clk_cnt
>
0
)
{
DBG
(
"pixclock: %lu"
,
hdmi
_bridge
->
pixclock
);
DBG
(
"pixclock: %lu"
,
hdmi
->
pixclock
);
ret
=
clk_set_rate
(
hdmi
->
pwr_clks
[
0
],
hdmi
_bridge
->
pixclock
);
ret
=
clk_set_rate
(
hdmi
->
pwr_clks
[
0
],
hdmi
->
pixclock
);
if
(
ret
)
{
if
(
ret
)
{
dev_err
(
dev
->
dev
,
"failed to set pixel clk: %s (%d)
\n
"
,
dev_err
(
dev
->
dev
,
"failed to set pixel clk: %s (%d)
\n
"
,
config
->
pwr_clk_names
[
0
],
ret
);
config
->
pwr_clk_names
[
0
],
ret
);
...
@@ -102,12 +98,13 @@ static void hdmi_bridge_pre_enable(struct drm_bridge *bridge)
...
@@ -102,12 +98,13 @@ static void hdmi_bridge_pre_enable(struct drm_bridge *bridge)
DBG
(
"power up"
);
DBG
(
"power up"
);
if
(
!
hdmi
_bridge
->
power_on
)
{
if
(
!
hdmi
->
power_on
)
{
power_on
(
bridge
);
power_on
(
bridge
);
hdmi_bridge
->
power_on
=
true
;
hdmi
->
power_on
=
true
;
hdmi_audio_update
(
hdmi
);
}
}
phy
->
funcs
->
powerup
(
phy
,
hdmi
_bridge
->
pixclock
);
phy
->
funcs
->
powerup
(
phy
,
hdmi
->
pixclock
);
hdmi_set_mode
(
hdmi
,
true
);
hdmi_set_mode
(
hdmi
,
true
);
}
}
...
@@ -129,9 +126,10 @@ static void hdmi_bridge_post_disable(struct drm_bridge *bridge)
...
@@ -129,9 +126,10 @@ static void hdmi_bridge_post_disable(struct drm_bridge *bridge)
hdmi_set_mode
(
hdmi
,
false
);
hdmi_set_mode
(
hdmi
,
false
);
phy
->
funcs
->
powerdown
(
phy
);
phy
->
funcs
->
powerdown
(
phy
);
if
(
hdmi
_bridge
->
power_on
)
{
if
(
hdmi
->
power_on
)
{
power_off
(
bridge
);
power_off
(
bridge
);
hdmi_bridge
->
power_on
=
false
;
hdmi
->
power_on
=
false
;
hdmi_audio_update
(
hdmi
);
}
}
}
}
...
@@ -146,7 +144,7 @@ static void hdmi_bridge_mode_set(struct drm_bridge *bridge,
...
@@ -146,7 +144,7 @@ static void hdmi_bridge_mode_set(struct drm_bridge *bridge,
mode
=
adjusted_mode
;
mode
=
adjusted_mode
;
hdmi
_bridge
->
pixclock
=
mode
->
clock
*
1000
;
hdmi
->
pixclock
=
mode
->
clock
*
1000
;
hdmi
->
hdmi_mode
=
drm_match_cea_mode
(
mode
)
>
1
;
hdmi
->
hdmi_mode
=
drm_match_cea_mode
(
mode
)
>
1
;
...
@@ -194,9 +192,7 @@ static void hdmi_bridge_mode_set(struct drm_bridge *bridge,
...
@@ -194,9 +192,7 @@ static void hdmi_bridge_mode_set(struct drm_bridge *bridge,
DBG
(
"frame_ctrl=%08x"
,
frame_ctrl
);
DBG
(
"frame_ctrl=%08x"
,
frame_ctrl
);
hdmi_write
(
hdmi
,
REG_HDMI_FRAME_CTRL
,
frame_ctrl
);
hdmi_write
(
hdmi
,
REG_HDMI_FRAME_CTRL
,
frame_ctrl
);
// TODO until we have audio, this might be safest:
hdmi_audio_update
(
hdmi
);
if
(
hdmi
->
hdmi_mode
)
hdmi_write
(
hdmi
,
REG_HDMI_GC
,
HDMI_GC_MUTE
);
}
}
static
const
struct
drm_bridge_funcs
hdmi_bridge_funcs
=
{
static
const
struct
drm_bridge_funcs
hdmi_bridge_funcs
=
{
...
...
编辑
预览
Markdown
is supported
0%
请重试
或
添加新附件
.
添加附件
取消
You are about to add
0
people
to the discussion. Proceed with caution.
先完成此消息的编辑!
取消
想要评论请
注册
或
登录