root/arch/mips/alchemy/common/vss.c

/* [<][>][^][v][top][bottom][index][help] */

DEFINITIONS

This source file includes following definitions.
  1. __enable_block
  2. __disable_block
  3. au1300_vss_block_control

   1 // SPDX-License-Identifier: GPL-2.0-only
   2 /*
   3  * Au1300 media block power gating (VSS)
   4  *
   5  * This is a stop-gap solution until I have the clock framework integration
   6  * ready. This stuff here really must be handled transparently when clocks
   7  * for various media blocks are enabled/disabled.
   8  */
   9 
  10 #include <linux/export.h>
  11 #include <linux/spinlock.h>
  12 #include <asm/mach-au1x00/au1000.h>
  13 
  14 #define VSS_GATE        0x00    /* gate wait timers */
  15 #define VSS_CLKRST      0x04    /* clock/block control */
  16 #define VSS_FTR         0x08    /* footers */
  17 
  18 #define VSS_ADDR(blk)   (KSEG1ADDR(AU1300_VSS_PHYS_ADDR) + (blk * 0x0c))
  19 
  20 static DEFINE_SPINLOCK(au1300_vss_lock);
  21 
  22 /* enable a block as outlined in the databook */
  23 static inline void __enable_block(int block)
  24 {
  25         void __iomem *base = (void __iomem *)VSS_ADDR(block);
  26 
  27         __raw_writel(3, base + VSS_CLKRST);     /* enable clock, assert reset */
  28         wmb();
  29 
  30         __raw_writel(0x01fffffe, base + VSS_GATE); /* maximum setup time */
  31         wmb();
  32 
  33         /* enable footers in sequence */
  34         __raw_writel(0x01, base + VSS_FTR);
  35         wmb();
  36         __raw_writel(0x03, base + VSS_FTR);
  37         wmb();
  38         __raw_writel(0x07, base + VSS_FTR);
  39         wmb();
  40         __raw_writel(0x0f, base + VSS_FTR);
  41         wmb();
  42 
  43         __raw_writel(0x01ffffff, base + VSS_GATE); /* start FSM too */
  44         wmb();
  45 
  46         __raw_writel(2, base + VSS_CLKRST);     /* deassert reset */
  47         wmb();
  48 
  49         __raw_writel(0x1f, base + VSS_FTR);     /* enable isolation cells */
  50         wmb();
  51 }
  52 
  53 /* disable a block as outlined in the databook */
  54 static inline void __disable_block(int block)
  55 {
  56         void __iomem *base = (void __iomem *)VSS_ADDR(block);
  57 
  58         __raw_writel(0x0f, base + VSS_FTR);     /* disable isolation cells */
  59         wmb();
  60         __raw_writel(0, base + VSS_GATE);       /* disable FSM */
  61         wmb();
  62         __raw_writel(3, base + VSS_CLKRST);     /* assert reset */
  63         wmb();
  64         __raw_writel(1, base + VSS_CLKRST);     /* disable clock */
  65         wmb();
  66         __raw_writel(0, base + VSS_FTR);        /* disable all footers */
  67         wmb();
  68 }
  69 
  70 void au1300_vss_block_control(int block, int enable)
  71 {
  72         unsigned long flags;
  73 
  74         if (alchemy_get_cputype() != ALCHEMY_CPU_AU1300)
  75                 return;
  76 
  77         /* only one block at a time */
  78         spin_lock_irqsave(&au1300_vss_lock, flags);
  79         if (enable)
  80                 __enable_block(block);
  81         else
  82                 __disable_block(block);
  83         spin_unlock_irqrestore(&au1300_vss_lock, flags);
  84 }
  85 EXPORT_SYMBOL_GPL(au1300_vss_block_control);

/* [<][>][^][v][top][bottom][index][help] */