Commit e2e0136476397be4fccd16569bbe0695d591c979

Authored by Vaibhav Hiremath
1 parent f0b5a75f1f
Exists in master

arm:omap:am33xx: Cleanup and fix PRM code

There were some custom API's being introduced for GFX and PRUSS
module clk_enable/disable, in order to bring the module out-of-reset.
Although there are HWMOD hooks available for doing same thing, so
now using generic omap2 clock API's, replacing these custom API's.

This will mean, deleting prcm33xx.h and clock33xx.c

Showing 8 changed files with 127 additions and 168 deletions Side-by-side Diff

arch/arm/mach-omap2/Makefile
... ... @@ -147,7 +147,7 @@
147 147 clock3517.o clock36xx.o \
148 148 dpll3xxx.o clock3xxx_data.o \
149 149 clkt_iclk.o
150   -obj-$(CONFIG_SOC_OMAPAM33XX) += clock33xx_data.o clock33xx.o
  150 +obj-$(CONFIG_SOC_OMAPAM33XX) += clock33xx_data.o
151 151 obj-$(CONFIG_ARCH_OMAP4) += $(clock-common) clock44xx_data.o \
152 152 dpll3xxx.o dpll44xx.o
153 153  
arch/arm/mach-omap2/clock33xx.c
1   -/*
2   - * AM33XX specific clock ops.
3   - *
4   - * Copyright (C) 2011 Texas Instruments, Inc. - http://www.ti.com/
5   - *
6   - * This program is free software; you can redistribute it and/or
7   - * modify it under the terms of the GNU General Public License as
8   - * published by the Free Software Foundation version 2.
9   - *
10   - * This program is distributed "as is" WITHOUT ANY WARRANTY of any
11   - * kind, whether express or implied; without even the implied warranty
12   - * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13   - * GNU General Public License for more details.
14   - *
15   - * Part of this code are based on code by Hemant Padenkar.
16   - */
17   -
18   -#include <linux/kernel.h>
19   -#include <linux/clk.h>
20   -#include <linux/io.h>
21   -
22   -#include <plat/clock.h>
23   -#include <plat/prcm.h>
24   -
25   -#include "clock.h"
26   -#include "cm-regbits-33xx.h"
27   -
28   -#include "prm33xx.h"
29   -#include "prm-regbits-33xx.h"
30   -
31   -#include "prm2xxx_3xxx.h"
32   -
33   -/**
34   - * am33xx_dflt_wait_clk_enable() - Enable a am33xx module clock
35   - * @clk: Pointer to the clock to be enabled
36   - *
37   - * This function just wraps omap2_dflt_clk_enable with a check for module idle
38   - * status. We loop till module goes to funcitonal state as the immediate access
39   - * to module space will not work otherwise.
40   - */
41   -int am33xx_dflt_wait_clk_enable(struct clk *clk)
42   -{
43   - omap2_dflt_clk_enable(clk);
44   -
45   - omap2_cm_wait_idlest(clk->enable_reg, AM33XX_IDLEST_MASK,
46   - AM33XX_IDLEST_VAL, clk->name);
47   -
48   - return 0;
49   -}
50   -
51   -int am33xx_sgx_clk_enable(struct clk *clk)
52   -{
53   - omap2_dflt_clk_enable(clk);
54   -
55   - /* De-assert local reset after module enable */
56   - omap2_prm_clear_mod_reg_bits(AM33XX_GFX_RST_MASK,
57   - AM33XX_PRM_GFX_MOD,
58   - AM33XX_RM_GFX_RSTCTRL_OFFSET);
59   -
60   - omap2_cm_wait_idlest(clk->enable_reg, AM33XX_IDLEST_MASK,
61   - AM33XX_IDLEST_VAL, clk->name);
62   -
63   - return 0;
64   -}
65   -
66   -void am33xx_sgx_clk_disable(struct clk *clk)
67   -{
68   - /* Assert local reset */
69   - omap2_prm_set_mod_reg_bits(AM33XX_GFX_RST_MASK,
70   - AM33XX_PRM_GFX_MOD,
71   - AM33XX_RM_GFX_RSTCTRL_OFFSET);
72   -
73   - omap2_dflt_clk_disable(clk);
74   -}
75   -
76   -int am33xx_icss_clk_enable(struct clk *clk)
77   -{
78   - omap2_dflt_clk_enable(clk);
79   -
80   - /* De-assert local reset after module enable */
81   - omap2_prm_clear_mod_reg_bits(AM33XX_ICSS_LRST_MASK,
82   - AM33XX_PRM_PER_MOD,
83   - AM33XX_RM_PER_RSTCTRL_OFFSET);
84   -
85   - omap2_cm_wait_idlest(clk->enable_reg, AM33XX_IDLEST_MASK,
86   - AM33XX_IDLEST_VAL, clk->name);
87   -
88   - return 0;
89   -}
90   -
91   -void am33xx_icss_clk_disable(struct clk *clk)
92   -{
93   - /* Assert local reset */
94   - omap2_prm_set_mod_reg_bits(AM33XX_ICSS_LRST_MASK,
95   - AM33XX_PRM_PER_MOD,
96   - AM33XX_RM_PER_RSTCTRL_OFFSET);
97   -
98   - omap2_dflt_clk_disable(clk);
99   -}
100   -
101   -const struct clkops clkops_am33xx_dflt_wait = {
102   - .enable = am33xx_dflt_wait_clk_enable,
103   - .disable = omap2_dflt_clk_disable,
104   -};
105   -
106   -const struct clkops clkops_am33xx_sgx = {
107   - .enable = am33xx_sgx_clk_enable,
108   - .disable = am33xx_sgx_clk_disable,
109   -};
110   -
111   -const struct clkops clkops_am33xx_icss = {
112   - .enable = am33xx_icss_clk_enable,
113   - .disable = am33xx_icss_clk_disable,
114   -};
arch/arm/mach-omap2/cminst33xx.c
... ... @@ -24,7 +24,6 @@
24 24 #include "cminst33xx.h"
25 25 #include "cm-regbits-34xx.h"
26 26 #include "cm-regbits-33xx.h"
27   -#include "prcm33xx.h"
28 27 #include "prm33xx.h"
29 28  
30 29 /*
arch/arm/mach-omap2/omap_hwmod.c
... ... @@ -150,7 +150,9 @@
150 150 #include "cminst33xx.h"
151 151 #include "prm2xxx_3xxx.h"
152 152 #include "prm44xx.h"
  153 +#include "prm33xx.h"
153 154 #include "prminst44xx.h"
  155 +#include "prminst33xx.h"
154 156 #include "mux.h"
155 157  
156 158 /* Maximum microseconds to wait for OMAP module to softreset */
... ... @@ -1256,7 +1258,11 @@
1256 1258 if (IS_ERR_VALUE(ret))
1257 1259 return ret;
1258 1260  
1259   - if (cpu_is_omap24xx() || cpu_is_omap34xx())
  1261 + if (cpu_is_am33xx()) {
  1262 + return am33xx_prminst_assert_hardreset(
  1263 + oh->clkdm->pwrdm.ptr->prcm_offs,
  1264 + ohri.rst_shift);
  1265 + } else if (cpu_is_omap24xx() || cpu_is_omap34xx())
1260 1266 return omap2_prm_assert_hardreset(oh->prcm.omap2.module_offs,
1261 1267 ohri.rst_shift);
1262 1268 else if (cpu_is_omap44xx())
... ... @@ -1290,7 +1296,11 @@
1290 1296 if (IS_ERR_VALUE(ret))
1291 1297 return ret;
1292 1298  
1293   - if (cpu_is_omap24xx() || cpu_is_omap34xx()) {
  1299 + if (cpu_is_am33xx()) {
  1300 + ret = am33xx_prminst_deassert_hardreset(
  1301 + oh->clkdm->pwrdm.ptr->prcm_offs,
  1302 + ohri.rst_shift, ohri.st_shift);
  1303 + } else if (cpu_is_omap24xx() || cpu_is_omap34xx()) {
1294 1304 ret = omap2_prm_deassert_hardreset(oh->prcm.omap2.module_offs,
1295 1305 ohri.rst_shift,
1296 1306 ohri.st_shift);
... ... @@ -1332,7 +1342,11 @@
1332 1342 if (IS_ERR_VALUE(ret))
1333 1343 return ret;
1334 1344  
1335   - if (cpu_is_omap24xx() || cpu_is_omap34xx()) {
  1345 + if (cpu_is_am33xx()) {
  1346 + return am33xx_prminst_is_hardreset_asserted(
  1347 + oh->clkdm->pwrdm.ptr->prcm_offs,
  1348 + AM33XX_PM_RSTST, ohri.st_shift);
  1349 + } else if (cpu_is_omap24xx() || cpu_is_omap34xx()) {
1336 1350 return omap2_prm_is_hardreset_asserted(oh->prcm.omap2.module_offs,
1337 1351 ohri.st_shift);
1338 1352 } else if (cpu_is_omap44xx()) {
arch/arm/mach-omap2/prcm33xx.h
1   -/*
2   - * AM33XX PRCM definitions
3   - *
4   - * Copyright (C) 2010 Texas Instruments, Inc.
5   - *
6   - * Vaibhav Hiremath <hvaibhav@ti.com>
7   - *
8   - * This program is free software; you can redistribute it and/or modify
9   - * it under the terms of the GNU General Public License version 2 as
10   - * published by the Free Software Foundation.
11   - *
12   - * This file contains macros and functions that are common to all of
13   - * the PRM/CM/PRCM blocks on the OMAP4 devices: PRM and CM
14   - */
15   -
16   -#ifndef __ARCH_ARM_MACH_OMAP2_PRCM33XX_H
17   -#define __ARCH_ARM_MACH_OMAP2_PRCM33XX_H
18   -
19   -/*
20   - * AM33XX PRCM partition IDs
21   - *
22   - * The numbers and order are arbitrary, but 0 is reserved for the
23   - * 'invalid' partition in case someone forgets to add a
24   - * .prcm_partition field.
25   - */
26   -#define AM33XX_INVALID_PRCM_PARTITION 0
27   -#define AM33XX_PRM_PARTITION 1
28   -#define AM33XX_CM_PARTITION 2
29   -
30   -/*
31   - * AM33XX_MAX_PRCM_PARTITIONS: set to the highest value of the PRCM partition
32   - * IDs, plus one
33   - */
34   -#define AM33XX_MAX_PRCM_PARTITIONS 3
35   -
36   -#endif
arch/arm/mach-omap2/prm33xx.h
... ... @@ -37,10 +37,11 @@
37 37 #define AM33XX_PRM_GFX_MOD 0x1100
38 38 #define AM33XX_PRM_CEFUSE_MOD 0x1200
39 39  
40   -/* OMAP4 specific register offsets */
  40 +/* Register offsets (used from OMAP4) */
41 41 #define AM33XX_PM_PWSTCTRL 0x0000
42 42 #define AM33XX_PM_PWSTST 0x0004
43   -
  43 +#define AM33XX_PM_RSTCTRL 0x0008
  44 +#define AM33XX_PM_RSTST 0x000C
44 45  
45 46 /* PRM */
46 47  
arch/arm/mach-omap2/prminst33xx.c
... ... @@ -27,17 +27,23 @@
27 27  
28 28 #define AM33XX_PRM_MOD_SIZE 0x100
29 29 #define AM33XX_PRM_MOD_START AM33XX_PRM_PER_MOD
30   -#define PRM_REG_SZ 0x4
  30 +#define PRM_REG_SZ 0x4
31 31  
32   -static u16 off_fixup[][2] = {
33   - { 0xC, 0x8 }, /* AM33XX_PRM_PER_MOD */
34   - { 0x4, 0x8 }, /* AM33XX_PRM_WKUP_MOD */
35   - { 0x0, 0x4 }, /* AM33XX_PRM_MPU_MOD */
  32 +/*
  33 + * PRM Offsets are screwed up, and they are not consistent across modules.
  34 + * Below are the offsets for PWRSTCTRL and PWRSTST for respective modules.
  35 + * Fields are -
  36 + * PWRSTST, PWRSTCTRL, RSTCTRL, RSTST
  37 + */
  38 +static u16 off_fixup[][4] = {
  39 + { 0x0C, 0x08, 0x00, 0x04 }, /* AM33XX_PRM_PER_MOD */
  40 + { 0x04, 0x08, 0x00, 0x0C }, /* AM33XX_PRM_WKUP_MOD */
  41 + { 0x00, 0x04, 0x08, 0x08 }, /* AM33XX_PRM_MPU_MOD */
36 42 /* XXX: PRM_DEVICE: offsets are invalid for powerdomain*/
37   - { 0x0, 0x0 }, /* AM33XX_PRM_DEVICE_MOD */
38   - { 0x0, 0x4 }, /* AM33XX_PRM_RTC_MOD */
39   - { 0x0, 0x10 }, /* AM33XX_PRM_GFX_MOD */
40   - { 0x0, 0x4 }, /* AM33XX_PRM_CEFUSE_MOD */
  43 + { 0x00, 0x00, 0x00, 0x08 }, /* AM33XX_PRM_DEVICE_MOD */
  44 + { 0x00, 0x04, 0x00, 0x00 }, /* AM33XX_PRM_RTC_MOD */
  45 + { 0x00, 0x10, 0x04, 0x14 }, /* AM33XX_PRM_GFX_MOD */
  46 + { 0x00, 0x04, 0x00, 0x00 }, /* AM33XX_PRM_CEFUSE_MOD */
41 47 };
42 48  
43 49 /* Read a register in a PRM instance */
... ... @@ -57,8 +63,7 @@
57 63 }
58 64  
59 65 /* Read-modify-write a register in PRM. Caller must lock */
60   -u32 am33xx_prminst_rmw_inst_reg_bits(u32 mask, u32 bits, s16 inst,
61   - s16 idx)
  66 +u32 am33xx_prminst_rmw_inst_reg_bits(u32 mask, u32 bits, s16 inst, s16 idx)
62 67 {
63 68 u32 v;
64 69  
... ... @@ -68,5 +73,91 @@
68 73 am33xx_prminst_write_inst_reg(v, inst, idx);
69 74  
70 75 return v;
  76 +}
  77 +
  78 +/**
  79 + * am33xx_prminst_is_hardreset_asserted - read the HW reset line state of
  80 + * submodules contained in the hwmod module
  81 + * @prm_mod: PRM submodule base (e.g. CORE_MOD)
  82 + * @idx: register bit offset for calculating correct offset
  83 + * @mask: register bit mask
  84 + *
  85 + * Returns 1 if the (sub)module hardreset line is currently asserted,
  86 + * 0 if the (sub)module hardreset line is not currently asserted, or
  87 + * -EINVAL if called while running on a non-OMAP2/3 chip.
  88 + */
  89 +
  90 +u32 am33xx_prminst_is_hardreset_asserted(s16 prm_mod, s16 idx, u32 mask)
  91 +{
  92 + u32 v;
  93 +
  94 + v = am33xx_prminst_read_inst_reg(prm_mod, idx);
  95 + v &= mask;
  96 + v >>= __ffs(mask);
  97 +
  98 + return v;
  99 +}
  100 +
  101 +/**
  102 + * am33xx_prminst_assert_hardreset - assert the HW reset line of a submodule
  103 + * @prm_mod: PRM submodule base (e.g. GFX_MOD)
  104 + * @shift: register bit shift corresponding to the reset line to assert
  105 + *
  106 + * Some IPs like iva or PRUSS contain processors that require an HW
  107 + * reset line to be asserted / deasserted in order to fully enable the
  108 + * IP. These modules may have multiple hard-reset lines that reset
  109 + * different 'submodules' inside the IP block. This function will
  110 + * place the submodule into reset. Returns 0 upon success or -EINVAL
  111 + * upon an argument error.
  112 + */
  113 +
  114 +int am33xx_prminst_assert_hardreset(s16 prm_mod, u8 shift)
  115 +{
  116 + u32 mask;
  117 +
  118 + if (!cpu_is_am33xx())
  119 + return -EINVAL;
  120 +
  121 + mask = 1 << shift;
  122 + /* assert the reset control line */
  123 + am33xx_prminst_rmw_inst_reg_bits(mask, mask, prm_mod, AM33XX_PM_RSTCTRL);
  124 +
  125 + return 0;
  126 +}
  127 +
  128 +/**
  129 + * am33xx_prminst_deassert_hardreset - deassert a submodule hardreset line and
  130 + * wait
  131 + * @prm_mod: PRM submodule base (e.g. CORE_MOD)
  132 + * @rst_shift: register bit shift corresponding to the reset line to deassert
  133 + * @st_shift: register bit shift for the status of the deasserted submodule
  134 + *
  135 + * Some IPs like SGX, PRUSS and M3 contain processors that require an HW
  136 + * reset line to be asserted / deasserted in order to fully enable the
  137 + * IP.
  138 + * This function will take the submodule out of reset and wait until the
  139 + * PRCM indicates that the reset has completed before returning.
  140 + * Returns 0 upon success or -EINVAL upon an argument error,
  141 + * -EEXIST if the submodule was already out of reset, or -EBUSY if the
  142 + * submodule did not exit reset promptly.
  143 + */
  144 +int am33xx_prminst_deassert_hardreset(s16 prm_mod, u8 rst_shift, u8 st_shift)
  145 +{
  146 + u32 rst, st;
  147 +
  148 + if (!cpu_is_am33xx())
  149 + return -EINVAL;
  150 +
  151 + rst = 1 << rst_shift;
  152 + st = 1 << st_shift;
  153 +
  154 + /* Clear the reset status by writing 1 to the status bit */
  155 + am33xx_prminst_rmw_inst_reg_bits(0xffffffff, st, prm_mod,
  156 + AM33XX_PM_RSTST);
  157 + /* de-assert the reset control line */
  158 + am33xx_prminst_rmw_inst_reg_bits(rst, 0, prm_mod, AM33XX_PM_RSTCTRL);
  159 + /* TODO: wait the status to be set */
  160 +
  161 + return 0;
71 162 }
arch/arm/mach-omap2/prminst33xx.h
... ... @@ -24,6 +24,10 @@
24 24 extern void am33xx_prminst_write_inst_reg(u32 val, s16 inst, u16 idx);
25 25 extern u32 am33xx_prminst_rmw_inst_reg_bits(u32 mask, u32 bits,
26 26 s16 inst, s16 idx);
  27 +extern u32 am33xx_prminst_is_hardreset_asserted(s16 domain, s16 idx, u32 mask);
  28 +extern int am33xx_prminst_assert_hardreset(s16 prm_mod, u8 shift);
  29 +extern int am33xx_prminst_deassert_hardreset(s16 prm_mod, u8 rst_shift, u8
  30 + st_shift);
27 31  
28 32 extern void am33xx_prm_global_warm_sw_reset(void);
29 33