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