diff options
-rw-r--r-- | arch/arm/boot/dts/imx6sl.dtsi | 7 | ||||
-rw-r--r-- | arch/arm/mach-imx/gpc.c | 69 |
2 files changed, 73 insertions, 3 deletions
diff --git a/arch/arm/boot/dts/imx6sl.dtsi b/arch/arm/boot/dts/imx6sl.dtsi index b751542f71c7..605fefbc99d8 100644 --- a/arch/arm/boot/dts/imx6sl.dtsi +++ b/arch/arm/boot/dts/imx6sl.dtsi | |||
@@ -601,8 +601,11 @@ | |||
601 | reg = <0x020dc000 0x4000>; | 601 | reg = <0x020dc000 0x4000>; |
602 | interrupts = <0 89 0x04>; | 602 | interrupts = <0 89 0x04>; |
603 | clocks = <&clks IMX6SL_CLK_GPU2D_PODF>, <&clks IMX6SL_CLK_GPU2D_OVG>, | 603 | clocks = <&clks IMX6SL_CLK_GPU2D_PODF>, <&clks IMX6SL_CLK_GPU2D_OVG>, |
604 | <&clks IMX6SL_CLK_IPG>; | 604 | <&clks IMX6SL_CLK_IPG>, <&clks IMX6SL_CLK_LCDIF_AXI>, |
605 | clock-names = "gpu2d_podf", "gpu2d_ovg", "ipg"; | 605 | <&clks IMX6SL_CLK_LCDIF_PIX>, <&clks IMX6SL_CLK_EPDC_AXI>, |
606 | <&clks IMX6SL_CLK_EPDC_PIX>, <&clks IMX6SL_CLK_PXP_AXI>; | ||
607 | clock-names = "gpu2d_podf", "gpu2d_ovg", "ipg", "lcd_axi", | ||
608 | "lcd_pix", "epdc_axi", "epdc_pix", "pxp_axi"; | ||
606 | pu-supply = <®_pu>; | 609 | pu-supply = <®_pu>; |
607 | }; | 610 | }; |
608 | 611 | ||
diff --git a/arch/arm/mach-imx/gpc.c b/arch/arm/mach-imx/gpc.c index 2a3646b4d027..97343277d1e8 100644 --- a/arch/arm/mach-imx/gpc.c +++ b/arch/arm/mach-imx/gpc.c | |||
@@ -31,6 +31,10 @@ | |||
31 | #define GPC_PGC_GPU_PDN 0x260 | 31 | #define GPC_PGC_GPU_PDN 0x260 |
32 | #define GPC_PGC_GPU_PUPSCR 0x264 | 32 | #define GPC_PGC_GPU_PUPSCR 0x264 |
33 | #define GPC_PGC_GPU_PDNSCR 0x268 | 33 | #define GPC_PGC_GPU_PDNSCR 0x268 |
34 | #define GPC_PGC_DISP_PGCR_OFFSET 0x240 | ||
35 | #define GPC_PGC_DISP_PUPSCR_OFFSET 0x244 | ||
36 | #define GPC_PGC_DISP_PDNSCR_OFFSET 0x248 | ||
37 | #define GPC_PGC_DISP_SR_OFFSET 0x24c | ||
34 | #define GPC_PGC_GPU_SW_SHIFT 0 | 38 | #define GPC_PGC_GPU_SW_SHIFT 0 |
35 | #define GPC_PGC_GPU_SW_MASK 0x3f | 39 | #define GPC_PGC_GPU_SW_MASK 0x3f |
36 | #define GPC_PGC_GPU_SW2ISO_SHIFT 8 | 40 | #define GPC_PGC_GPU_SW2ISO_SHIFT 8 |
@@ -51,6 +55,8 @@ static void __iomem *gpc_base; | |||
51 | static u32 gpc_wake_irqs[IMR_NUM]; | 55 | static u32 gpc_wake_irqs[IMR_NUM]; |
52 | static u32 gpc_saved_imrs[IMR_NUM]; | 56 | static u32 gpc_saved_imrs[IMR_NUM]; |
53 | static struct clk *gpu3d_clk, *gpu3d_shader_clk, *gpu2d_clk, *gpu2d_axi_clk; | 57 | static struct clk *gpu3d_clk, *gpu3d_shader_clk, *gpu2d_clk, *gpu2d_axi_clk; |
58 | static struct clk *lcd_axi_clk, *lcd_pix_clk, *epdc_axi_clk, *epdc_pix_clk; | ||
59 | static struct clk *pxp_axi_clk; | ||
54 | static struct clk *openvg_axi_clk, *vpu_clk, *ipg_clk; | 60 | static struct clk *openvg_axi_clk, *vpu_clk, *ipg_clk; |
55 | static struct device *gpc_dev; | 61 | static struct device *gpc_dev; |
56 | struct regulator *pu_reg; | 62 | struct regulator *pu_reg; |
@@ -65,11 +71,63 @@ static struct regulator_init_data pu_dummy_initdata = { | |||
65 | }; | 71 | }; |
66 | static int pu_dummy_enable; | 72 | static int pu_dummy_enable; |
67 | 73 | ||
74 | static void imx_disp_clk(bool enable) | ||
75 | { | ||
76 | if (enable) { | ||
77 | clk_prepare_enable(lcd_axi_clk); | ||
78 | clk_prepare_enable(lcd_pix_clk); | ||
79 | clk_prepare_enable(epdc_axi_clk); | ||
80 | clk_prepare_enable(epdc_pix_clk); | ||
81 | clk_prepare_enable(pxp_axi_clk); | ||
82 | } else { | ||
83 | clk_disable_unprepare(lcd_axi_clk); | ||
84 | clk_disable_unprepare(lcd_pix_clk); | ||
85 | clk_disable_unprepare(epdc_axi_clk); | ||
86 | clk_disable_unprepare(epdc_pix_clk); | ||
87 | clk_disable_unprepare(pxp_axi_clk); | ||
88 | } | ||
89 | } | ||
90 | |||
91 | static void imx_gpc_dispmix_on(void) | ||
92 | { | ||
93 | if (cpu_is_imx6sl()) { | ||
94 | imx_disp_clk(true); | ||
95 | |||
96 | writel_relaxed(0x0, gpc_base + GPC_PGC_DISP_PGCR_OFFSET); | ||
97 | writel_relaxed(0x20, gpc_base + GPC_CNTR); | ||
98 | while (readl_relaxed(gpc_base + GPC_CNTR) & 0x20) | ||
99 | ; | ||
100 | writel_relaxed(0x1, gpc_base + GPC_PGC_DISP_SR_OFFSET); | ||
101 | |||
102 | imx_disp_clk(false); | ||
103 | } | ||
104 | } | ||
105 | |||
106 | static void imx_gpc_dispmix_off(void) | ||
107 | { | ||
108 | if (cpu_is_imx6sl()) { | ||
109 | imx_disp_clk(true); | ||
110 | |||
111 | writel_relaxed(0xFFFFFFFF, | ||
112 | gpc_base + GPC_PGC_DISP_PUPSCR_OFFSET); | ||
113 | writel_relaxed(0xFFFFFFFF, | ||
114 | gpc_base + GPC_PGC_DISP_PDNSCR_OFFSET); | ||
115 | writel_relaxed(0x1, gpc_base + GPC_PGC_DISP_PGCR_OFFSET); | ||
116 | writel_relaxed(0x10, gpc_base + GPC_CNTR); | ||
117 | while (readl_relaxed(gpc_base + GPC_CNTR) & 0x10) | ||
118 | ; | ||
119 | |||
120 | imx_disp_clk(false); | ||
121 | } | ||
122 | } | ||
123 | |||
68 | void imx_gpc_pre_suspend(bool arm_power_off) | 124 | void imx_gpc_pre_suspend(bool arm_power_off) |
69 | { | 125 | { |
70 | void __iomem *reg_imr1 = gpc_base + GPC_IMR1; | 126 | void __iomem *reg_imr1 = gpc_base + GPC_IMR1; |
71 | int i; | 127 | int i; |
72 | 128 | ||
129 | imx_gpc_dispmix_off(); | ||
130 | |||
73 | if (arm_power_off) | 131 | if (arm_power_off) |
74 | /* Tell GPC to power off ARM core when suspend */ | 132 | /* Tell GPC to power off ARM core when suspend */ |
75 | writel_relaxed(0x1, gpc_base + GPC_PGC_CPU_PDN); | 133 | writel_relaxed(0x1, gpc_base + GPC_PGC_CPU_PDN); |
@@ -90,6 +148,8 @@ void imx_gpc_post_resume(void) | |||
90 | 148 | ||
91 | for (i = 0; i < IMR_NUM; i++) | 149 | for (i = 0; i < IMR_NUM; i++) |
92 | writel_relaxed(gpc_saved_imrs[i], reg_imr1 + i * 4); | 150 | writel_relaxed(gpc_saved_imrs[i], reg_imr1 + i * 4); |
151 | |||
152 | imx_gpc_dispmix_on(); | ||
93 | } | 153 | } |
94 | 154 | ||
95 | static int imx_gpc_irq_set_wake(struct irq_data *d, unsigned int on) | 155 | static int imx_gpc_irq_set_wake(struct irq_data *d, unsigned int on) |
@@ -420,8 +480,15 @@ static int imx_gpc_probe(struct platform_device *pdev) | |||
420 | gpu2d_clk = devm_clk_get(gpc_dev, "gpu2d_podf"); | 480 | gpu2d_clk = devm_clk_get(gpc_dev, "gpu2d_podf"); |
421 | openvg_axi_clk = devm_clk_get(gpc_dev, "gpu2d_ovg"); | 481 | openvg_axi_clk = devm_clk_get(gpc_dev, "gpu2d_ovg"); |
422 | ipg_clk = devm_clk_get(gpc_dev, "ipg"); | 482 | ipg_clk = devm_clk_get(gpc_dev, "ipg"); |
483 | lcd_axi_clk = devm_clk_get(gpc_dev, "lcd_axi"); | ||
484 | lcd_pix_clk = devm_clk_get(gpc_dev, "lcd_pix"); | ||
485 | epdc_axi_clk = devm_clk_get(gpc_dev, "epdc_axi"); | ||
486 | epdc_pix_clk = devm_clk_get(gpc_dev, "epdc_pix"); | ||
487 | pxp_axi_clk = devm_clk_get(gpc_dev, "pxp_axi"); | ||
423 | if (IS_ERR(gpu2d_clk) || IS_ERR(openvg_axi_clk) | 488 | if (IS_ERR(gpu2d_clk) || IS_ERR(openvg_axi_clk) |
424 | || IS_ERR(ipg_clk)) { | 489 | || IS_ERR(ipg_clk) || IS_ERR(lcd_axi_clk) |
490 | || IS_ERR(lcd_pix_clk) || IS_ERR(epdc_axi_clk) | ||
491 | || IS_ERR(epdc_pix_clk) || IS_ERR(pxp_axi_clk)) { | ||
425 | dev_err(gpc_dev, "failed to get clk!\n"); | 492 | dev_err(gpc_dev, "failed to get clk!\n"); |
426 | return -ENOENT; | 493 | return -ENOENT; |
427 | } | 494 | } |