Skip to content
体验新版
项目
组织
正在加载...
登录
切换导航
打开侧边栏
openeuler
raspberrypi-kernel
提交
40cb1981
R
raspberrypi-kernel
项目概览
openeuler
/
raspberrypi-kernel
通知
13
Star
1
Fork
0
代码
文件
提交
分支
Tags
贡献者
分支图
Diff
Issue
0
列表
看板
标记
里程碑
合并请求
0
Wiki
0
Wiki
分析
仓库
DevOps
项目成员
Pages
R
raspberrypi-kernel
项目概览
项目概览
详情
发布
仓库
仓库
文件
提交
分支
标签
贡献者
分支图
比较
Issue
0
Issue
0
列表
看板
标记
里程碑
合并请求
0
合并请求
0
Pages
分析
分析
仓库分析
DevOps
Wiki
0
Wiki
成员
成员
收起侧边栏
关闭侧边栏
动态
分支图
创建新Issue
提交
Issue看板
提交
40cb1981
编写于
3月 30, 2015
作者:
S
Shawn Guo
浏览文件
操作
浏览文件
下载
差异文件
Merge branch 'imx/soc' into imx/dt
上级
dc98b0cb
ae4aee95
变更
7
隐藏空白更改
内联
并排
Showing
7 changed file
with
293 addition
and
9 deletion
+293
-9
Documentation/devicetree/bindings/power/fsl,imx-gpc.txt
Documentation/devicetree/bindings/power/fsl,imx-gpc.txt
+59
-0
arch/arm/mach-imx/Kconfig
arch/arm/mach-imx/Kconfig
+3
-0
arch/arm/mach-imx/clk-imx6q.c
arch/arm/mach-imx/clk-imx6q.c
+6
-2
arch/arm/mach-imx/gpc.c
arch/arm/mach-imx/gpc.c
+213
-0
drivers/bus/imx-weim.c
drivers/bus/imx-weim.c
+7
-6
include/dt-bindings/clock/imx6qdl-clock.h
include/dt-bindings/clock/imx6qdl-clock.h
+4
-1
include/linux/mfd/syscon/imx6q-iomuxc-gpr.h
include/linux/mfd/syscon/imx6q-iomuxc-gpr.h
+1
-0
未找到文件。
Documentation/devicetree/bindings/power/fsl,imx-gpc.txt
0 → 100644
浏览文件 @
40cb1981
Freescale i.MX General Power Controller
=======================================
The i.MX6Q General Power Control (GPC) block contains DVFS load tracking
counters and Power Gating Control (PGC) for the CPU and PU (GPU/VPU) power
domains.
Required properties:
- compatible: Should be "fsl,imx6q-gpc" or "fsl,imx6sl-gpc"
- reg: should be register base and length as documented in the
datasheet
- interrupts: Should contain GPC interrupt request 1
- pu-supply: Link to the LDO regulator powering the PU power domain
- clocks: Clock phandles to devices in the PU power domain that need
to be enabled during domain power-up for reset propagation.
- #power-domain-cells: Should be 1, see below:
The gpc node is a power-controller as documented by the generic power domain
bindings in Documentation/devicetree/bindings/power/power_domain.txt.
Example:
gpc: gpc@020dc000 {
compatible = "fsl,imx6q-gpc";
reg = <0x020dc000 0x4000>;
interrupts = <0 89 IRQ_TYPE_LEVEL_HIGH>,
<0 90 IRQ_TYPE_LEVEL_HIGH>;
pu-supply = <®_pu>;
clocks = <&clks IMX6QDL_CLK_GPU3D_CORE>,
<&clks IMX6QDL_CLK_GPU3D_SHADER>,
<&clks IMX6QDL_CLK_GPU2D_CORE>,
<&clks IMX6QDL_CLK_GPU2D_AXI>,
<&clks IMX6QDL_CLK_OPENVG_AXI>,
<&clks IMX6QDL_CLK_VPU_AXI>;
#power-domain-cells = <1>;
};
Specifying power domain for IP modules
======================================
IP cores belonging to a power domain should contain a 'power-domains' property
that is a phandle pointing to the gpc device node and a DOMAIN_INDEX specifying
the power domain the device belongs to.
Example of a device that is part of the PU power domain:
vpu: vpu@02040000 {
reg = <0x02040000 0x3c000>;
/* ... */
power-domains = <&gpc 1>;
/* ... */
};
The following DOMAIN_INDEX values are valid for i.MX6Q:
ARM_DOMAIN 0
PU_DOMAIN 1
The following additional DOMAIN_INDEX value is valid for i.MX6SL:
DISPLAY_DOMAIN 2
arch/arm/mach-imx/Kconfig
浏览文件 @
40cb1981
...
...
@@ -21,6 +21,7 @@ config MXC_AVIC
config MXC_DEBUG_BOARD
bool "Enable MXC debug board(for 3-stack)"
depends on MACH_MX27_3DS || MACH_MX31_3DS || MACH_MX35_3DS
help
The debug board is an integral part of the MXC 3-stack(PDK)
platforms, it can be attached or removed from the peripheral
...
...
@@ -50,6 +51,7 @@ config HAVE_IMX_ANATOP
config HAVE_IMX_GPC
bool
select PM_GENERIC_DOMAINS if PM
config HAVE_IMX_MMDC
bool
...
...
@@ -585,6 +587,7 @@ config SOC_VF610
select ARM_GIC
select PINCTRL_VF610
select PL310_ERRATA_769419 if CACHE_L2X0
select SMP_ON_UP if SMP
help
This enables support for Freescale Vybrid VF610 processor.
...
...
arch/arm/mach-imx/clk-imx6q.c
浏览文件 @
40cb1981
...
...
@@ -119,6 +119,7 @@ static unsigned int share_count_asrc;
static
unsigned
int
share_count_ssi1
;
static
unsigned
int
share_count_ssi2
;
static
unsigned
int
share_count_ssi3
;
static
unsigned
int
share_count_mipi_core_cfg
;
static
void
__init
imx6q_clocks_init
(
struct
device_node
*
ccm_node
)
{
...
...
@@ -246,6 +247,7 @@ static void __init imx6q_clocks_init(struct device_node *ccm_node)
clk
[
IMX6QDL_CLK_PLL3_60M
]
=
imx_clk_fixed_factor
(
"pll3_60m"
,
"pll3_usb_otg"
,
1
,
8
);
clk
[
IMX6QDL_CLK_TWD
]
=
imx_clk_fixed_factor
(
"twd"
,
"arm"
,
1
,
2
);
clk
[
IMX6QDL_CLK_GPT_3M
]
=
imx_clk_fixed_factor
(
"gpt_3m"
,
"osc"
,
1
,
8
);
clk
[
IMX6QDL_CLK_VIDEO_27M
]
=
imx_clk_fixed_factor
(
"video_27m"
,
"pll3_pfd1_540m"
,
1
,
20
);
if
(
cpu_is_imx6dl
())
{
clk
[
IMX6QDL_CLK_GPU2D_AXI
]
=
imx_clk_fixed_factor
(
"gpu2d_axi"
,
"mmdc_ch0_axi_podf"
,
1
,
1
);
clk
[
IMX6QDL_CLK_GPU3D_AXI
]
=
imx_clk_fixed_factor
(
"gpu3d_axi"
,
"mmdc_ch0_axi_podf"
,
1
,
1
);
...
...
@@ -400,7 +402,7 @@ static void __init imx6q_clocks_init(struct device_node *ccm_node)
clk
[
IMX6QDL_CLK_GPU2D_CORE
]
=
imx_clk_gate2
(
"gpu2d_core"
,
"gpu2d_core_podf"
,
base
+
0x6c
,
24
);
clk
[
IMX6QDL_CLK_GPU3D_CORE
]
=
imx_clk_gate2
(
"gpu3d_core"
,
"gpu3d_core_podf"
,
base
+
0x6c
,
26
);
clk
[
IMX6QDL_CLK_HDMI_IAHB
]
=
imx_clk_gate2
(
"hdmi_iahb"
,
"ahb"
,
base
+
0x70
,
0
);
clk
[
IMX6QDL_CLK_HDMI_ISFR
]
=
imx_clk_gate2
(
"hdmi_isfr"
,
"
pll3_pfd1_540m"
,
base
+
0x70
,
4
);
clk
[
IMX6QDL_CLK_HDMI_ISFR
]
=
imx_clk_gate2
(
"hdmi_isfr"
,
"
video_27m"
,
base
+
0x70
,
4
);
clk
[
IMX6QDL_CLK_I2C1
]
=
imx_clk_gate2
(
"i2c1"
,
"ipg_per"
,
base
+
0x70
,
6
);
clk
[
IMX6QDL_CLK_I2C2
]
=
imx_clk_gate2
(
"i2c2"
,
"ipg_per"
,
base
+
0x70
,
8
);
clk
[
IMX6QDL_CLK_I2C3
]
=
imx_clk_gate2
(
"i2c3"
,
"ipg_per"
,
base
+
0x70
,
10
);
...
...
@@ -415,7 +417,9 @@ static void __init imx6q_clocks_init(struct device_node *ccm_node)
clk
[
IMX6QDL_CLK_LDB_DI0
]
=
imx_clk_gate2
(
"ldb_di0"
,
"ldb_di0_podf"
,
base
+
0x74
,
12
);
clk
[
IMX6QDL_CLK_LDB_DI1
]
=
imx_clk_gate2
(
"ldb_di1"
,
"ldb_di1_podf"
,
base
+
0x74
,
14
);
clk
[
IMX6QDL_CLK_IPU2_DI1
]
=
imx_clk_gate2
(
"ipu2_di1"
,
"ipu2_di1_sel"
,
base
+
0x74
,
10
);
clk
[
IMX6QDL_CLK_HSI_TX
]
=
imx_clk_gate2
(
"hsi_tx"
,
"hsi_tx_podf"
,
base
+
0x74
,
16
);
clk
[
IMX6QDL_CLK_HSI_TX
]
=
imx_clk_gate2_shared
(
"hsi_tx"
,
"hsi_tx_podf"
,
base
+
0x74
,
16
,
&
share_count_mipi_core_cfg
);
clk
[
IMX6QDL_CLK_MIPI_CORE_CFG
]
=
imx_clk_gate2_shared
(
"mipi_core_cfg"
,
"video_27m"
,
base
+
0x74
,
16
,
&
share_count_mipi_core_cfg
);
clk
[
IMX6QDL_CLK_MIPI_IPG
]
=
imx_clk_gate2_shared
(
"mipi_ipg"
,
"ipg"
,
base
+
0x74
,
16
,
&
share_count_mipi_core_cfg
);
if
(
cpu_is_imx6dl
())
/*
* The multiplexer and divider of the imx6q clock gpu2d get
...
...
arch/arm/mach-imx/gpc.c
浏览文件 @
40cb1981
...
...
@@ -10,15 +10,25 @@
* http://www.gnu.org/copyleft/gpl.html
*/
#include <linux/clk.h>
#include <linux/delay.h>
#include <linux/io.h>
#include <linux/irq.h>
#include <linux/of.h>
#include <linux/of_address.h>
#include <linux/of_irq.h>
#include <linux/platform_device.h>
#include <linux/pm_domain.h>
#include <linux/regulator/consumer.h>
#include <linux/irqchip/arm-gic.h>
#include "common.h"
#include "hardware.h"
#define GPC_CNTR 0x000
#define GPC_IMR1 0x008
#define GPC_PGC_GPU_PDN 0x260
#define GPC_PGC_GPU_PUPSCR 0x264
#define GPC_PGC_GPU_PDNSCR 0x268
#define GPC_PGC_CPU_PDN 0x2a0
#define GPC_PGC_CPU_PUPSCR 0x2a4
#define GPC_PGC_CPU_PDNSCR 0x2a8
...
...
@@ -27,6 +37,18 @@
#define IMR_NUM 4
#define GPU_VPU_PUP_REQ BIT(1)
#define GPU_VPU_PDN_REQ BIT(0)
#define GPC_CLK_MAX 6
struct
pu_domain
{
struct
generic_pm_domain
base
;
struct
regulator
*
reg
;
struct
clk
*
clk
[
GPC_CLK_MAX
];
int
num_clks
;
};
static
void
__iomem
*
gpc_base
;
static
u32
gpc_wake_irqs
[
IMR_NUM
];
static
u32
gpc_saved_imrs
[
IMR_NUM
];
...
...
@@ -170,3 +192,194 @@ void __init imx_gpc_init(void)
gic_arch_extn
.
irq_unmask
=
imx_gpc_irq_unmask
;
gic_arch_extn
.
irq_set_wake
=
imx_gpc_irq_set_wake
;
}
#ifdef CONFIG_PM_GENERIC_DOMAINS
static
void
_imx6q_pm_pu_power_off
(
struct
generic_pm_domain
*
genpd
)
{
int
iso
,
iso2sw
;
u32
val
;
/* Read ISO and ISO2SW power down delays */
val
=
readl_relaxed
(
gpc_base
+
GPC_PGC_GPU_PDNSCR
);
iso
=
val
&
0x3f
;
iso2sw
=
(
val
>>
8
)
&
0x3f
;
/* Gate off PU domain when GPU/VPU when powered down */
writel_relaxed
(
0x1
,
gpc_base
+
GPC_PGC_GPU_PDN
);
/* Request GPC to power down GPU/VPU */
val
=
readl_relaxed
(
gpc_base
+
GPC_CNTR
);
val
|=
GPU_VPU_PDN_REQ
;
writel_relaxed
(
val
,
gpc_base
+
GPC_CNTR
);
/* Wait ISO + ISO2SW IPG clock cycles */
ndelay
((
iso
+
iso2sw
)
*
1000
/
66
);
}
static
int
imx6q_pm_pu_power_off
(
struct
generic_pm_domain
*
genpd
)
{
struct
pu_domain
*
pu
=
container_of
(
genpd
,
struct
pu_domain
,
base
);
_imx6q_pm_pu_power_off
(
genpd
);
if
(
pu
->
reg
)
regulator_disable
(
pu
->
reg
);
return
0
;
}
static
int
imx6q_pm_pu_power_on
(
struct
generic_pm_domain
*
genpd
)
{
struct
pu_domain
*
pu
=
container_of
(
genpd
,
struct
pu_domain
,
base
);
int
i
,
ret
,
sw
,
sw2iso
;
u32
val
;
if
(
pu
->
reg
)
ret
=
regulator_enable
(
pu
->
reg
);
if
(
pu
->
reg
&&
ret
)
{
pr_err
(
"%s: failed to enable regulator: %d
\n
"
,
__func__
,
ret
);
return
ret
;
}
/* Enable reset clocks for all devices in the PU domain */
for
(
i
=
0
;
i
<
pu
->
num_clks
;
i
++
)
clk_prepare_enable
(
pu
->
clk
[
i
]);
/* Gate off PU domain when GPU/VPU when powered down */
writel_relaxed
(
0x1
,
gpc_base
+
GPC_PGC_GPU_PDN
);
/* Read ISO and ISO2SW power down delays */
val
=
readl_relaxed
(
gpc_base
+
GPC_PGC_GPU_PUPSCR
);
sw
=
val
&
0x3f
;
sw2iso
=
(
val
>>
8
)
&
0x3f
;
/* Request GPC to power up GPU/VPU */
val
=
readl_relaxed
(
gpc_base
+
GPC_CNTR
);
val
|=
GPU_VPU_PUP_REQ
;
writel_relaxed
(
val
,
gpc_base
+
GPC_CNTR
);
/* Wait ISO + ISO2SW IPG clock cycles */
ndelay
((
sw
+
sw2iso
)
*
1000
/
66
);
/* Disable reset clocks for all devices in the PU domain */
for
(
i
=
0
;
i
<
pu
->
num_clks
;
i
++
)
clk_disable_unprepare
(
pu
->
clk
[
i
]);
return
0
;
}
static
struct
generic_pm_domain
imx6q_arm_domain
=
{
.
name
=
"ARM"
,
};
static
struct
pu_domain
imx6q_pu_domain
=
{
.
base
=
{
.
name
=
"PU"
,
.
power_off
=
imx6q_pm_pu_power_off
,
.
power_on
=
imx6q_pm_pu_power_on
,
.
power_off_latency_ns
=
25000
,
.
power_on_latency_ns
=
2000000
,
},
};
static
struct
generic_pm_domain
imx6sl_display_domain
=
{
.
name
=
"DISPLAY"
,
};
static
struct
generic_pm_domain
*
imx_gpc_domains
[]
=
{
&
imx6q_arm_domain
,
&
imx6q_pu_domain
.
base
,
&
imx6sl_display_domain
,
};
static
struct
genpd_onecell_data
imx_gpc_onecell_data
=
{
.
domains
=
imx_gpc_domains
,
.
num_domains
=
ARRAY_SIZE
(
imx_gpc_domains
),
};
static
int
imx_gpc_genpd_init
(
struct
device
*
dev
,
struct
regulator
*
pu_reg
)
{
struct
clk
*
clk
;
bool
is_off
;
int
i
;
imx6q_pu_domain
.
reg
=
pu_reg
;
for
(
i
=
0
;
;
i
++
)
{
clk
=
of_clk_get
(
dev
->
of_node
,
i
);
if
(
IS_ERR
(
clk
))
break
;
if
(
i
>=
GPC_CLK_MAX
)
{
dev_err
(
dev
,
"more than %d clocks
\n
"
,
GPC_CLK_MAX
);
goto
clk_err
;
}
imx6q_pu_domain
.
clk
[
i
]
=
clk
;
}
imx6q_pu_domain
.
num_clks
=
i
;
is_off
=
IS_ENABLED
(
CONFIG_PM
);
if
(
is_off
)
{
_imx6q_pm_pu_power_off
(
&
imx6q_pu_domain
.
base
);
}
else
{
/*
* Enable power if compiled without CONFIG_PM in case the
* bootloader disabled it.
*/
imx6q_pm_pu_power_on
(
&
imx6q_pu_domain
.
base
);
}
pm_genpd_init
(
&
imx6q_pu_domain
.
base
,
NULL
,
is_off
);
return
of_genpd_add_provider_onecell
(
dev
->
of_node
,
&
imx_gpc_onecell_data
);
clk_err:
while
(
i
--
)
clk_put
(
imx6q_pu_domain
.
clk
[
i
]);
return
-
EINVAL
;
}
#else
static
inline
int
imx_gpc_genpd_init
(
struct
device
*
dev
,
struct
regulator
*
reg
)
{
return
0
;
}
#endif
/* CONFIG_PM_GENERIC_DOMAINS */
static
int
imx_gpc_probe
(
struct
platform_device
*
pdev
)
{
struct
regulator
*
pu_reg
;
int
ret
;
pu_reg
=
devm_regulator_get_optional
(
&
pdev
->
dev
,
"pu"
);
if
(
PTR_ERR
(
pu_reg
)
==
-
ENODEV
)
pu_reg
=
NULL
;
if
(
IS_ERR
(
pu_reg
))
{
ret
=
PTR_ERR
(
pu_reg
);
dev_err
(
&
pdev
->
dev
,
"failed to get pu regulator: %d
\n
"
,
ret
);
return
ret
;
}
return
imx_gpc_genpd_init
(
&
pdev
->
dev
,
pu_reg
);
}
static
const
struct
of_device_id
imx_gpc_dt_ids
[]
=
{
{
.
compatible
=
"fsl,imx6q-gpc"
},
{
.
compatible
=
"fsl,imx6sl-gpc"
},
{
}
};
static
struct
platform_driver
imx_gpc_driver
=
{
.
driver
=
{
.
name
=
"imx-gpc"
,
.
owner
=
THIS_MODULE
,
.
of_match_table
=
imx_gpc_dt_ids
,
},
.
probe
=
imx_gpc_probe
,
};
static
int
__init
imx_pgc_init
(
void
)
{
return
platform_driver_register
(
&
imx_gpc_driver
);
}
subsys_initcall
(
imx_pgc_init
);
drivers/bus/imx-weim.c
浏览文件 @
40cb1981
...
...
@@ -142,7 +142,7 @@ static int __init weim_parse_dt(struct platform_device *pdev,
&
pdev
->
dev
);
const
struct
imx_weim_devtype
*
devtype
=
of_id
->
data
;
struct
device_node
*
child
;
int
ret
;
int
ret
,
have_child
=
0
;
if
(
devtype
==
&
imx50_weim_devtype
)
{
ret
=
imx_weim_gpr_setup
(
pdev
);
...
...
@@ -155,14 +155,15 @@ static int __init weim_parse_dt(struct platform_device *pdev,
continue
;
ret
=
weim_timing_setup
(
child
,
base
,
devtype
);
if
(
ret
)
{
dev_
err
(
&
pdev
->
dev
,
"%s set timing failed.
\n
"
,
if
(
ret
)
dev_
warn
(
&
pdev
->
dev
,
"%s set timing failed.
\n
"
,
child
->
full_name
);
return
ret
;
}
else
have_child
=
1
;
}
ret
=
of_platform_populate
(
pdev
->
dev
.
of_node
,
if
(
have_child
)
ret
=
of_platform_populate
(
pdev
->
dev
.
of_node
,
of_default_bus_match_table
,
NULL
,
&
pdev
->
dev
);
if
(
ret
)
...
...
include/dt-bindings/clock/imx6qdl-clock.h
浏览文件 @
40cb1981
...
...
@@ -248,6 +248,9 @@
#define IMX6QDL_PLL6_BYPASS 235
#define IMX6QDL_PLL7_BYPASS 236
#define IMX6QDL_CLK_GPT_3M 237
#define IMX6QDL_CLK_END 238
#define IMX6QDL_CLK_VIDEO_27M 238
#define IMX6QDL_CLK_MIPI_CORE_CFG 239
#define IMX6QDL_CLK_MIPI_IPG 240
#define IMX6QDL_CLK_END 241
#endif
/* __DT_BINDINGS_CLOCK_IMX6QDL_H */
include/linux/mfd/syscon/imx6q-iomuxc-gpr.h
浏览文件 @
40cb1981
...
...
@@ -207,6 +207,7 @@
#define IMX6Q_GPR3_LVDS0_MUX_CTL_IPU1_DI1 (0x1 << 6)
#define IMX6Q_GPR3_LVDS0_MUX_CTL_IPU2_DI0 (0x2 << 6)
#define IMX6Q_GPR3_LVDS0_MUX_CTL_IPU2_DI1 (0x3 << 6)
#define IMX6Q_GPR3_MIPI_MUX_CTL_SHIFT 4
#define IMX6Q_GPR3_MIPI_MUX_CTL_MASK (0x3 << 4)
#define IMX6Q_GPR3_MIPI_MUX_CTL_IPU1_DI0 (0x0 << 4)
#define IMX6Q_GPR3_MIPI_MUX_CTL_IPU1_DI1 (0x1 << 4)
...
...
编辑
预览
Markdown
is supported
0%
请重试
或
添加新附件
.
添加附件
取消
You are about to add
0
people
to the discussion. Proceed with caution.
先完成此消息的编辑!
取消
想要评论请
注册
或
登录