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
Kirill Smelkov
linux
Commits
40cb1981
Commit
40cb1981
authored
Mar 30, 2015
by
Shawn Guo
Browse files
Options
Browse Files
Download
Plain Diff
Merge branch 'imx/soc' into imx/dt
parents
dc98b0cb
ae4aee95
Changes
7
Hide whitespace changes
Inline
Side-by-side
Showing
7 changed files
with
293 additions
and
9 deletions
+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
No files found.
Documentation/devicetree/bindings/power/fsl,imx-gpc.txt
0 → 100644
View file @
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
View file @
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
View file @
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
View file @
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
View file @
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
View file @
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
View file @
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)
...
...
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