1 /* 2 * arch/sh/kernel/cpu/sh4a/ubc.c 3 * 4 * On-chip UBC support for SH-4A CPUs. 5 * 6 * Copyright (C) 2009 - 2010 Paul Mundt 7 * 8 * This file is subject to the terms and conditions of the GNU General Public 9 * License. See the file "COPYING" in the main directory of this archive 10 * for more details. 11 */ 12 #include <linux/init.h> 13 #include <linux/err.h> 14 #include <linux/clk.h> 15 #include <linux/io.h> 16 #include <asm/hw_breakpoint.h> 17 18 #define UBC_CBR(idx) (0xff200000 + (0x20 * idx)) 19 #define UBC_CRR(idx) (0xff200004 + (0x20 * idx)) 20 #define UBC_CAR(idx) (0xff200008 + (0x20 * idx)) 21 #define UBC_CAMR(idx) (0xff20000c + (0x20 * idx)) 22 23 #define UBC_CCMFR 0xff200600 24 #define UBC_CBCR 0xff200620 25 26 /* CRR */ 27 #define UBC_CRR_PCB (1 << 1) 28 #define UBC_CRR_BIE (1 << 0) 29 30 /* CBR */ 31 #define UBC_CBR_CE (1 << 0) 32 33 static struct sh_ubc sh4a_ubc; 34 35 static void sh4a_ubc_enable(struct arch_hw_breakpoint *info, int idx) 36 { 37 __raw_writel(UBC_CBR_CE | info->len | info->type, UBC_CBR(idx)); 38 __raw_writel(info->address, UBC_CAR(idx)); 39 } 40 41 static void sh4a_ubc_disable(struct arch_hw_breakpoint *info, int idx) 42 { 43 __raw_writel(0, UBC_CBR(idx)); 44 __raw_writel(0, UBC_CAR(idx)); 45 } 46 47 static void sh4a_ubc_enable_all(unsigned long mask) 48 { 49 int i; 50 51 for (i = 0; i < sh4a_ubc.num_events; i++) 52 if (mask & (1 << i)) 53 __raw_writel(__raw_readl(UBC_CBR(i)) | UBC_CBR_CE, 54 UBC_CBR(i)); 55 } 56 57 static void sh4a_ubc_disable_all(void) 58 { 59 int i; 60 61 for (i = 0; i < sh4a_ubc.num_events; i++) 62 __raw_writel(__raw_readl(UBC_CBR(i)) & ~UBC_CBR_CE, 63 UBC_CBR(i)); 64 } 65 66 static unsigned long sh4a_ubc_active_mask(void) 67 { 68 unsigned long active = 0; 69 int i; 70 71 for (i = 0; i < sh4a_ubc.num_events; i++) 72 if (__raw_readl(UBC_CBR(i)) & UBC_CBR_CE) 73 active |= (1 << i); 74 75 return active; 76 } 77 78 static unsigned long sh4a_ubc_triggered_mask(void) 79 { 80 return __raw_readl(UBC_CCMFR); 81 } 82 83 static void sh4a_ubc_clear_triggered_mask(unsigned long mask) 84 { 85 __raw_writel(__raw_readl(UBC_CCMFR) & ~mask, UBC_CCMFR); 86 } 87 88 static struct sh_ubc sh4a_ubc = { 89 .name = "SH-4A", 90 .num_events = 2, 91 .trap_nr = 0x1e0, 92 .enable = sh4a_ubc_enable, 93 .disable = sh4a_ubc_disable, 94 .enable_all = sh4a_ubc_enable_all, 95 .disable_all = sh4a_ubc_disable_all, 96 .active_mask = sh4a_ubc_active_mask, 97 .triggered_mask = sh4a_ubc_triggered_mask, 98 .clear_triggered_mask = sh4a_ubc_clear_triggered_mask, 99 }; 100 101 static int __init sh4a_ubc_init(void) 102 { 103 struct clk *ubc_iclk = clk_get(NULL, "ubc0"); 104 int i; 105 106 /* 107 * The UBC MSTP bit is optional, as not all platforms will have 108 * it. Just ignore it if we can't find it. 109 */ 110 if (IS_ERR(ubc_iclk)) 111 ubc_iclk = NULL; 112 113 clk_enable(ubc_iclk); 114 115 __raw_writel(0, UBC_CBCR); 116 117 for (i = 0; i < sh4a_ubc.num_events; i++) { 118 __raw_writel(0, UBC_CAMR(i)); 119 __raw_writel(0, UBC_CBR(i)); 120 121 __raw_writel(UBC_CRR_BIE | UBC_CRR_PCB, UBC_CRR(i)); 122 123 /* dummy read for write posting */ 124 (void)__raw_readl(UBC_CRR(i)); 125 } 126 127 clk_disable(ubc_iclk); 128 129 sh4a_ubc.clk = ubc_iclk; 130 131 return register_sh_ubc(&sh4a_ubc); 132 } 133 arch_initcall(sh4a_ubc_init); 134