linux/arch/frv/kernel/cmode.S
<<
>>
Prefs
   1/* cmode.S: clock mode management
   2 *
   3 * Copyright (C) 2004 Red Hat, Inc. All Rights Reserved.
   4 * Written by David Woodhouse (dwmw2@infradead.org)
   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
   8 * as published by the Free Software Foundation; either version
   9 * 2 of the License, or (at your option) any later version.
  10 *
  11 */
  12
  13#include <linux/sys.h>
  14#include <linux/linkage.h>
  15#include <asm/setup.h>
  16#include <asm/segment.h>
  17#include <asm/ptrace.h>
  18#include <asm/errno.h>
  19#include <asm/cache.h>
  20#include <asm/spr-regs.h>
  21
  22#define __addr_MASK     0xfeff9820      /* interrupt controller mask */
  23
  24#define __addr_SDRAMC   0xfe000400      /* SDRAM controller regs */
  25#define SDRAMC_DSTS     0x28            /* SDRAM status */
  26#define SDRAMC_DSTS_SSI 0x00000001      /* indicates that the SDRAM is in self-refresh mode */
  27#define SDRAMC_DRCN     0x30            /* SDRAM refresh control */
  28#define SDRAMC_DRCN_SR  0x00000001      /* transition SDRAM into self-refresh mode */
  29#define __addr_CLKC     0xfeff9a00
  30#define CLKC_SWCMODE    0x00000008
  31#define __addr_LEDS     0xe1200004
  32
  33.macro li v r
  34        sethi.p         %hi(\v),\r
  35        setlo           %lo(\v),\r
  36.endm
  37
  38        .text
  39        .balign         4
  40
  41
  42###############################################################################
  43#
  44# Change CMODE
  45# - void frv_change_cmode(int cmode)
  46#
  47###############################################################################
  48        .globl          frv_change_cmode
  49        .type           frv_change_cmode,@function
  50
  51.macro  LEDS v
  52#ifdef DEBUG_CMODE
  53        setlos  #~\v,gr10
  54        sti     gr10,@(gr11,#0)
  55        membar
  56#endif
  57.endm
  58
  59frv_change_cmode:
  60        movsg           lr,gr9
  61#ifdef DEBUG_CMODE
  62        li              __addr_LEDS,gr11
  63#endif
  64        dcef            @(gr0,gr0),#1
  65
  66        # Shift argument left by 24 bits to fit in SWCMODE register later.
  67        slli            gr8,#24,gr8
  68
  69        # (1) Set '0' in the PSR.ET bit, and prohibit interrupts.
  70        movsg           psr,gr14
  71        andi            gr14,#~PSR_ET,gr3
  72        movgs           gr3,psr
  73
  74#if 0 // Fujitsu recommend to skip this and will update docs.
  75        # (2) Set '0' to all bits of the MASK register of the interrupt
  76        #     controller, and mask interrupts.
  77        li              __addr_MASK,gr12
  78        ldi             @(gr12,#0),gr13
  79        li              0xffff0000,gr4
  80        sti             gr4,@(gr12,#0)
  81#endif
  82
  83        # (3) Stop the transfer function of DMAC. Stop all the bus masters
  84        #     to access SDRAM and the internal resources.
  85
  86        # (already done by caller)
  87
  88        # (4) Preload a series of following instructions to the instruction
  89        #     cache.
  90        li              #__cmode_icache_lock_start,gr3
  91        li              #__cmode_icache_lock_end,gr4
  92
  931:      icpl            gr3,gr0,#1
  94        addi            gr3,#L1_CACHE_BYTES,gr3
  95        cmp             gr4,gr3,icc0
  96        bhi             icc0,#0,1b
  97
  98        # Set up addresses in regs for later steps.
  99        setlos          SDRAMC_DRCN_SR,gr3
 100        li              __addr_SDRAMC,gr4
 101        li              __addr_CLKC,gr5
 102        ldi             @(gr5,#0),gr6
 103        li              #0x80000000,gr7
 104        or              gr6,gr7,gr6
 105
 106        bra             __cmode_icache_lock_start
 107
 108        .balign L1_CACHE_BYTES
 109__cmode_icache_lock_start:
 110
 111        # (5) Flush the content of all caches by the DCEF instruction.
 112        dcef            @(gr0,gr0),#1
 113
 114        # (6) Execute loading the dummy for SDRAM.
 115        ldi             @(gr9,#0),gr0
 116
 117        # (7) Set '1' to the DRCN.SR bit, and change SDRAM to the
 118        #     self-refresh mode. Execute the dummy load to all memory
 119        #     devices set to cacheable on the external bus side in parallel
 120        #     with this.
 121        sti             gr3,@(gr4,#SDRAMC_DRCN)
 122
 123        # (8) Execute memory barrier instruction (MEMBAR).
 124        membar
 125
 126        # (9) Read the DSTS register repeatedly until '1' stands in the
 127        #     DSTS.SSI field.
 1281:      ldi             @(gr4,#SDRAMC_DSTS),gr3
 129        andicc          gr3,#SDRAMC_DSTS_SSI,gr3,icc0
 130        beq             icc0,#0,1b
 131
 132        # (10) Execute memory barrier instruction (MEMBAR).
 133        membar
 134
 135#if 1
 136        # (11) Set the value of CMODE that you want to change to
 137        #      SWCMODE.SWCM[3:0].
 138        sti             gr8,@(gr5,#CLKC_SWCMODE)
 139
 140        # (12) Set '1' to the CLKC.SWEN bit. In that case, do not change
 141        #      fields other than SWEN of the CLKC register.
 142        sti             gr6,@(gr5,#0)
 143#endif
 144        # (13) Execute the instruction just after the memory barrier
 145        # instruction that executes the self-loop 256 times. (Meanwhile,
 146        # the CMODE switch is done.)
 147        membar
 148        setlos          #256,gr7
 1492:      subicc          gr7,#1,gr7,icc0
 150        bne             icc0,#2,2b
 151
 152        LEDS    0x36
 153
 154        # (14) Release the self-refresh of SDRAM.
 155        sti             gr0,@(gr4,#SDRAMC_DRCN)
 156
 157        # Wait for it...
 1583:      ldi             @(gr4,#SDRAMC_DSTS),gr3
 159        andicc          gr3,#SDRAMC_DSTS_SSI,gr3,icc0
 160        bne             icc0,#2,3b
 161
 162#if 0
 163        li              0x0100000,gr10
 1644:      subicc          gr10,#1,gr10,icc0
 165
 166        bne             icc0,#0,4b
 167#endif
 168
 169__cmode_icache_lock_end:
 170
 171        li              #__cmode_icache_lock_start,gr3
 172        li              #__cmode_icache_lock_end,gr4
 173
 1744:      icul            gr3
 175        addi            gr3,#L1_CACHE_BYTES,gr3
 176        cmp             gr4,gr3,icc0
 177        bhi             icc0,#0,4b
 178
 179#if 0 // Fujitsu recommend to skip this and will update docs.
 180        # (15) Release the interrupt mask setting of the MASK register of
 181        # the interrupt controller if necessary.
 182        sti             gr13,@(gr12,#0)
 183#endif
 184        # (16) Set  1' in the PSR.ET bit, and permit interrupt.
 185        movgs           gr14,psr
 186
 187        bralr
 188
 189        .size           frv_change_cmode, .-frv_change_cmode
 190