/* cmode.S: clock mode management1*2* Copyright (C) 2004 Red Hat, Inc. All Rights Reserved.3* Written by David Woodhouse ([email protected])4*5* This program is free software; you can redistribute it and/or6* modify it under the terms of the GNU General Public License7* as published by the Free Software Foundation; either version8* 2 of the License, or (at your option) any later version.9*10*/1112#include <linux/sys.h>13#include <linux/linkage.h>14#include <asm/setup.h>15#include <asm/segment.h>16#include <asm/ptrace.h>17#include <asm/errno.h>18#include <asm/cache.h>19#include <asm/spr-regs.h>2021#define __addr_MASK 0xfeff9820 /* interrupt controller mask */2223#define __addr_SDRAMC 0xfe000400 /* SDRAM controller regs */24#define SDRAMC_DSTS 0x28 /* SDRAM status */25#define SDRAMC_DSTS_SSI 0x00000001 /* indicates that the SDRAM is in self-refresh mode */26#define SDRAMC_DRCN 0x30 /* SDRAM refresh control */27#define SDRAMC_DRCN_SR 0x00000001 /* transition SDRAM into self-refresh mode */28#define __addr_CLKC 0xfeff9a0029#define CLKC_SWCMODE 0x0000000830#define __addr_LEDS 0xe12000043132.macro li v r33sethi.p %hi(\v),\r34setlo %lo(\v),\r35.endm3637.text38.balign 4394041###############################################################################42#43# Change CMODE44# - void frv_change_cmode(int cmode)45#46###############################################################################47.globl frv_change_cmode48.type frv_change_cmode,@function4950.macro LEDS v51#ifdef DEBUG_CMODE52setlos #~\v,gr1053sti gr10,@(gr11,#0)54membar55#endif56.endm5758frv_change_cmode:59movsg lr,gr960#ifdef DEBUG_CMODE61li __addr_LEDS,gr1162#endif63dcef @(gr0,gr0),#16465# Shift argument left by 24 bits to fit in SWCMODE register later.66slli gr8,#24,gr86768# (1) Set '0' in the PSR.ET bit, and prohibit interrupts.69movsg psr,gr1470andi gr14,#~PSR_ET,gr371movgs gr3,psr7273#if 0 // Fujitsu recommend to skip this and will update docs.74# (2) Set '0' to all bits of the MASK register of the interrupt75# controller, and mask interrupts.76li __addr_MASK,gr1277ldi @(gr12,#0),gr1378li 0xffff0000,gr479sti gr4,@(gr12,#0)80#endif8182# (3) Stop the transfer function of DMAC. Stop all the bus masters83# to access SDRAM and the internal resources.8485# (already done by caller)8687# (4) Preload a series of following instructions to the instruction88# cache.89li #__cmode_icache_lock_start,gr390li #__cmode_icache_lock_end,gr491921: icpl gr3,gr0,#193addi gr3,#L1_CACHE_BYTES,gr394cmp gr4,gr3,icc095bhi icc0,#0,1b9697# Set up addresses in regs for later steps.98setlos SDRAMC_DRCN_SR,gr399li __addr_SDRAMC,gr4100li __addr_CLKC,gr5101ldi @(gr5,#0),gr6102li #0x80000000,gr7103or gr6,gr7,gr6104105bra __cmode_icache_lock_start106107.balign L1_CACHE_BYTES108__cmode_icache_lock_start:109110# (5) Flush the content of all caches by the DCEF instruction.111dcef @(gr0,gr0),#1112113# (6) Execute loading the dummy for SDRAM.114ldi @(gr9,#0),gr0115116# (7) Set '1' to the DRCN.SR bit, and change SDRAM to the117# self-refresh mode. Execute the dummy load to all memory118# devices set to cacheable on the external bus side in parallel119# with this.120sti gr3,@(gr4,#SDRAMC_DRCN)121122# (8) Execute memory barrier instruction (MEMBAR).123membar124125# (9) Read the DSTS register repeatedly until '1' stands in the126# DSTS.SSI field.1271: ldi @(gr4,#SDRAMC_DSTS),gr3128andicc gr3,#SDRAMC_DSTS_SSI,gr3,icc0129beq icc0,#0,1b130131# (10) Execute memory barrier instruction (MEMBAR).132membar133134#if 1135# (11) Set the value of CMODE that you want to change to136# SWCMODE.SWCM[3:0].137sti gr8,@(gr5,#CLKC_SWCMODE)138139# (12) Set '1' to the CLKC.SWEN bit. In that case, do not change140# fields other than SWEN of the CLKC register.141sti gr6,@(gr5,#0)142#endif143# (13) Execute the instruction just after the memory barrier144# instruction that executes the self-loop 256 times. (Meanwhile,145# the CMODE switch is done.)146membar147setlos #256,gr71482: subicc gr7,#1,gr7,icc0149bne icc0,#2,2b150151LEDS 0x36152153# (14) Release the self-refresh of SDRAM.154sti gr0,@(gr4,#SDRAMC_DRCN)155156# Wait for it...1573: ldi @(gr4,#SDRAMC_DSTS),gr3158andicc gr3,#SDRAMC_DSTS_SSI,gr3,icc0159bne icc0,#2,3b160161#if 0162li 0x0100000,gr101634: subicc gr10,#1,gr10,icc0164165bne icc0,#0,4b166#endif167168__cmode_icache_lock_end:169170li #__cmode_icache_lock_start,gr3171li #__cmode_icache_lock_end,gr41721734: icul gr3174addi gr3,#L1_CACHE_BYTES,gr3175cmp gr4,gr3,icc0176bhi icc0,#0,4b177178#if 0 // Fujitsu recommend to skip this and will update docs.179# (15) Release the interrupt mask setting of the MASK register of180# the interrupt controller if necessary.181sti gr13,@(gr12,#0)182#endif183# (16) Set 1' in the PSR.ET bit, and permit interrupt.184movgs gr14,psr185186bralr187188.size frv_change_cmode, .-frv_change_cmode189190191