Commit 0be1621a749907ada0101e4139a1f57168c5410b

Authored by Benoît Cousson
Committed by Paul Walmsley
1 parent 16b040129e

OMAP4: PRM: add module hard reset support

Most processor modules (e.g., DSP, IVA, IPU) on OMAPs can be reset
under the control of the PRM.  This patch adds an API for this purpose
for OMAP4 devices:

int omap4_prm_is_hardreset_asserted(void __iomem *rstctrl_reg, u8 shift);
int omap4_prm_assert_hardreset(void __iomem *rstctrl_reg, u8 shift);
int omap4_prm_deassert_hardreset(void __iomem *rstctrl_reg, u8 shift);

This API is intended to be used only by the hwmod code - a subsequent
patch will add that support to hwmod.

This patch is a collaboration between Benoît Cousson <b-cousson@ti.com>
and Paul Walmsley <paul@pwsan.com>.

Signed-off-by: Paul Walmsley <paul@pwsan.com>
Signed-off-by: Benoît Cousson <b-cousson@ti.com>
Tested-by: Kevin Hilman <khilman@deeprootsystems.com>

Showing 3 changed files with 129 additions and 2 deletions Side-by-side Diff

arch/arm/mach-omap2/Makefile
... ... @@ -15,7 +15,7 @@
15 15  
16 16 obj-$(CONFIG_ARCH_OMAP2) += $(omap-2-3-common) $(prcm-common) $(hwmod-common)
17 17 obj-$(CONFIG_ARCH_OMAP3) += $(omap-2-3-common) $(prcm-common) $(hwmod-common)
18   -obj-$(CONFIG_ARCH_OMAP4) += $(prcm-common) $(hwmod-common)
  18 +obj-$(CONFIG_ARCH_OMAP4) += $(prcm-common) prm44xx.o $(hwmod-common)
19 19  
20 20 obj-$(CONFIG_OMAP_MCBSP) += mcbsp.o
21 21  
arch/arm/mach-omap2/prm.h
... ... @@ -5,7 +5,7 @@
5 5 * OMAP2/3 Power/Reset Management (PRM) register definitions
6 6 *
7 7 * Copyright (C) 2007-2009 Texas Instruments, Inc.
8   - * Copyright (C) 2009 Nokia Corporation
  8 + * Copyright (C) 2010 Nokia Corporation
9 9 *
10 10 * Written by Paul Walmsley
11 11 *
... ... @@ -246,6 +246,10 @@
246 246 return prm_rmw_mod_reg_bits(bits, 0x0, module, idx);
247 247 }
248 248  
  249 +int omap4_prm_is_hardreset_asserted(void __iomem *rstctrl_reg, u8 shift);
  250 +int omap4_prm_assert_hardreset(void __iomem *rstctrl_reg, u8 shift);
  251 +int omap4_prm_deassert_hardreset(void __iomem *rstctrl_reg, u8 shift);
  252 +
249 253 #endif
250 254  
251 255 /*
... ... @@ -396,6 +400,13 @@
396 400 */
397 401 #define OMAP_POWERSTATE_SHIFT 0
398 402 #define OMAP_POWERSTATE_MASK (0x3 << 0)
  403 +
  404 +
  405 +/*
  406 + * MAX_MODULE_HARDRESET_WAIT: Maximum microseconds to wait for an OMAP
  407 + * submodule to exit hardreset
  408 + */
  409 +#define MAX_MODULE_HARDRESET_WAIT 10000
399 410  
400 411  
401 412 #endif
arch/arm/mach-omap2/prm44xx.c
  1 +/*
  2 + * OMAP4 PRM module functions
  3 + *
  4 + * Copyright (C) 2010 Texas Instruments, Inc.
  5 + * Copyright (C) 2010 Nokia Corporation
  6 + * Benoît Cousson
  7 + * Paul Walmsley
  8 + *
  9 + * This program is free software; you can redistribute it and/or modify
  10 + * it under the terms of the GNU General Public License version 2 as
  11 + * published by the Free Software Foundation.
  12 + */
  13 +
  14 +#include <linux/kernel.h>
  15 +#include <linux/delay.h>
  16 +#include <linux/errno.h>
  17 +#include <linux/err.h>
  18 +
  19 +#include <plat/common.h>
  20 +#include <plat/cpu.h>
  21 +#include <plat/prcm.h>
  22 +
  23 +#include "prm.h"
  24 +#include "prm-regbits-44xx.h"
  25 +
  26 +/*
  27 + * Address offset (in bytes) between the reset control and the reset
  28 + * status registers: 4 bytes on OMAP4
  29 + */
  30 +#define OMAP4_RST_CTRL_ST_OFFSET 4
  31 +
  32 +/**
  33 + * omap4_prm_is_hardreset_asserted - read the HW reset line state of
  34 + * submodules contained in the hwmod module
  35 + * @rstctrl_reg: RM_RSTCTRL register address for this module
  36 + * @shift: register bit shift corresponding to the reset line to check
  37 + *
  38 + * Returns 1 if the (sub)module hardreset line is currently asserted,
  39 + * 0 if the (sub)module hardreset line is not currently asserted, or
  40 + * -EINVAL upon parameter error.
  41 + */
  42 +int omap4_prm_is_hardreset_asserted(void __iomem *rstctrl_reg, u8 shift)
  43 +{
  44 + if (!cpu_is_omap44xx() || !rstctrl_reg)
  45 + return -EINVAL;
  46 +
  47 + return omap4_prm_read_bits_shift(rstctrl_reg, (1 << shift));
  48 +}
  49 +
  50 +/**
  51 + * omap4_prm_assert_hardreset - assert the HW reset line of a submodule
  52 + * @rstctrl_reg: RM_RSTCTRL register address for this module
  53 + * @shift: register bit shift corresponding to the reset line to assert
  54 + *
  55 + * Some IPs like dsp, ipu or iva contain processors that require an HW
  56 + * reset line to be asserted / deasserted in order to fully enable the
  57 + * IP. These modules may have multiple hard-reset lines that reset
  58 + * different 'submodules' inside the IP block. This function will
  59 + * place the submodule into reset. Returns 0 upon success or -EINVAL
  60 + * upon an argument error.
  61 + */
  62 +int omap4_prm_assert_hardreset(void __iomem *rstctrl_reg, u8 shift)
  63 +{
  64 + u32 mask;
  65 +
  66 + if (!cpu_is_omap44xx() || !rstctrl_reg)
  67 + return -EINVAL;
  68 +
  69 + mask = 1 << shift;
  70 + omap4_prm_rmw_reg_bits(mask, mask, rstctrl_reg);
  71 +
  72 + return 0;
  73 +}
  74 +
  75 +/**
  76 + * omap4_prm_deassert_hardreset - deassert a submodule hardreset line and wait
  77 + * @rstctrl_reg: RM_RSTCTRL register address for this module
  78 + * @shift: register bit shift corresponding to the reset line to deassert
  79 + *
  80 + * Some IPs like dsp, ipu or iva contain processors that require an HW
  81 + * reset line to be asserted / deasserted in order to fully enable the
  82 + * IP. These modules may have multiple hard-reset lines that reset
  83 + * different 'submodules' inside the IP block. This function will
  84 + * take the submodule out of reset and wait until the PRCM indicates
  85 + * that the reset has completed before returning. Returns 0 upon success or
  86 + * -EINVAL upon an argument error, -EEXIST if the submodule was already out
  87 + * of reset, or -EBUSY if the submodule did not exit reset promptly.
  88 + */
  89 +int omap4_prm_deassert_hardreset(void __iomem *rstctrl_reg, u8 shift)
  90 +{
  91 + u32 mask;
  92 + void __iomem *rstst_reg;
  93 + int c;
  94 +
  95 + if (!cpu_is_omap44xx() || !rstctrl_reg)
  96 + return -EINVAL;
  97 +
  98 + rstst_reg = rstctrl_reg + OMAP4_RST_CTRL_ST_OFFSET;
  99 +
  100 + mask = 1 << shift;
  101 +
  102 + /* Check the current status to avoid de-asserting the line twice */
  103 + if (omap4_prm_read_bits_shift(rstctrl_reg, mask) == 0)
  104 + return -EEXIST;
  105 +
  106 + /* Clear the reset status by writing 1 to the status bit */
  107 + omap4_prm_rmw_reg_bits(0xffffffff, mask, rstst_reg);
  108 + /* de-assert the reset control line */
  109 + omap4_prm_rmw_reg_bits(mask, 0, rstctrl_reg);
  110 + /* wait the status to be set */
  111 + omap_test_timeout(omap4_prm_read_bits_shift(rstst_reg, mask),
  112 + MAX_MODULE_HARDRESET_WAIT, c);
  113 +
  114 + return (c == MAX_MODULE_HARDRESET_WAIT) ? -EBUSY : 0;
  115 +}