/* * Carsten Langgaard, carstenl@mips.com * Copyright (C) 2002 MIPS Technologies, Inc. All rights reserved. * * This program is free software; you can distribute it and/or modify it * under the terms of the GNU General Public License (Version 2) as * published by the Free Software Foundation. * * This program is distributed in the hope it will be useful, but WITHOUT * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License * for more details. * * You should have received a copy of the GNU General Public License along * with this program; if not, write to the Free Software Foundation, Inc., * 59 Temple Place - Suite 330, Boston MA 02111-1307, USA. * * PUMA5 specific setup. */ #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #ifdef CONFIG_AVM_POWERMETER #include #endif/*--- #ifdef CONFIG_AVM_POWERMETER ---*/ #include #define PRINTK printk #if defined(PUMA_CLK_DEBUG) #define DBG_TRC PRINTK #else/*--- #if defined(PUMA_CLK_DEBUG) ---*/ #define DBG_TRC(arg...) #endif/*--- #else ---*//*--- #if defined(PUMA_CLK_DEBUG) ---*/ static struct proc_dir_entry *puma_change_clock_entry; /*------------------------------------------------------------------------------------------*\ \*------------------------------------------------------------------------------------------*/ static int __init puma_clk_switch_init(void); static inline unsigned int puma_norm_clock(unsigned int clk, int flag); unsigned int puma_get_clock(enum _avm_clock_id clock_id); /*------------------------------------------------------------------------------------------*\ \*------------------------------------------------------------------------------------------*/ int puma_change_clock_read(char* buf, char **start, off_t offset, int count, int *eof, void *data) { unsigned int len; unsigned int cpu_clk = puma_get_clock(avm_clock_id_cpu); unsigned int system_clk = puma_get_clock(avm_clock_id_system); unsigned int usb_clk = puma_get_clock(avm_clock_id_usb); unsigned int docsis_clk = puma_get_clock(avm_clock_id_docsis); unsigned int gmii_clk = puma_get_clock(avm_clock_id_gmii); unsigned int vlynq_clk = puma_get_clock(avm_clock_id_vlynq); unsigned int sflash_clk = puma_get_clock(avm_clock_id_sflash); unsigned int tdm_clk = puma_get_clock(avm_clock_id_tdm); sprintf(buf, "Clocks: " " CPU: %u %cHz" " SYSTEM: %u %cHz" " USB: %u %cHz" " DOCSIS: %u %cHz" " GMII: %u %cHz" " VLYNQ/VBUS: %u %cHz" " SFLASH: %u %cHz" " TDM: %u %cHz" "\n", puma_norm_clock(cpu_clk, 0), puma_norm_clock(cpu_clk, 1), puma_norm_clock(system_clk, 0), puma_norm_clock(system_clk, 1), puma_norm_clock(usb_clk, 0), puma_norm_clock(usb_clk, 1), puma_norm_clock(docsis_clk, 0), puma_norm_clock(docsis_clk, 1), puma_norm_clock(gmii_clk, 0), puma_norm_clock(gmii_clk, 1), puma_norm_clock(vlynq_clk, 0), puma_norm_clock(vlynq_clk, 1), puma_norm_clock(sflash_clk, 0), puma_norm_clock(sflash_clk, 1), puma_norm_clock(tdm_clk, 0), puma_norm_clock(tdm_clk, 1)); len = strlen(buf); return len; } /*--------------------------------------------------------------------------------*\ \*--------------------------------------------------------------------------------*/ int puma_change_clock_write(struct file *file, const char __user *buff, unsigned long count, void *data) { return -EFAULT; } /*--------------------------------------------------------------------------------*\ \*--------------------------------------------------------------------------------*/ static int __init puma_clk_switch_init(void) { puma_change_clock_entry = create_proc_entry("clocks", 06666, NULL); if(puma_change_clock_entry) { puma_change_clock_entry->read_proc = puma_change_clock_read; puma_change_clock_entry->write_proc = puma_change_clock_write; puma_change_clock_entry->data = NULL; } return 0; }; late_initcall(puma_clk_switch_init); #if defined(PUMA_CLK_DEBUG) /*--------------------------------------------------------------------------------*\ \*--------------------------------------------------------------------------------*/ static const char *puma_name_clock_id(enum _avm_clock_id clock_id) { return clock_id == avm_clock_id_non ? "id_non" : clock_id == avm_clock_id_cpu ? "id_cpu" : clock_id == avm_clock_id_system ? "id_system" : clock_id == avm_clock_id_usb ? "id_usb" : clock_id == avm_clock_id_docsis ? "id_docsis" : clock_id == avm_clock_id_gmii ? "id_gmii" : clock_id == avm_clock_id_vlynq ? "id_vlynq" : clock_id == avm_clock_id_sflash ? "id_sflash" : clock_id == avm_clock_id_tdm ? "id_tdm" : "id_unknown"; } #endif/*--- #if defined(PUMA_CLK_DEBUG) ---*/ /*--------------------------------------------------------------------------------*\ * flag = 0: liefere NormFrequenz sonst 'K', 'M', ' ' \*--------------------------------------------------------------------------------*/ static inline unsigned int puma_norm_clock(unsigned int clk, int flag) { const unsigned int MHZ = 1000000; if(flag == 0) { return ((clk / MHZ) * MHZ) == clk ? clk / MHZ : ((clk / 1000) * 1000) == clk ? clk / 1000 : clk; } return ((clk / MHZ) * MHZ) == clk ? 'M': ((clk / 1000) * 1000) == clk ? 'K' : ' '; } /*------------------------------------------------------------------------------------------*\ \*------------------------------------------------------------------------------------------*/ int __init puma_clk_init(void) { return 0; } arch_initcall(puma_clk_init); /*------------------------------------------------------------------------------------------*\ \*------------------------------------------------------------------------------------------*/ unsigned int puma_get_clock(enum _avm_clock_id clock_id) { unsigned int clk = 0; /*--- printk("[%s] clock_id=%d \n", __FUNCTION__, clock_id); ---*/ switch(clock_id) { /*----------------------------------------------------------------------------------*\ \*----------------------------------------------------------------------------------*/ case avm_clock_id_cpu: clk = PAL_sysClkcGetFreq (PAL_SYS_CLKC_ARM); break; case avm_clock_id_system: clk = PAL_sysClkcGetFreq (PAL_SYS_CLKC_SYSCLK2); break; case avm_clock_id_usb: clk = PAL_sysClkcGetFreq (PAL_SYS_CLKC_USB); break; case avm_clock_id_docsis: clk = PAL_sysClkcGetFreq (PAL_SYS_CLKC_DOCSIS); break; case avm_clock_id_gmii: clk = PAL_sysClkcGetFreq (PAL_SYS_CLKC_GMII); break; case avm_clock_id_vlynq: clk = PAL_sysClkcGetFreq (PAL_SYS_CLKC_VLYNQ); break; case avm_clock_id_vbus: clk = PAL_sysClkcGetFreq (PAL_SYS_CLKC_SYSCLK3); break; case avm_clock_id_sflash: clk = PAL_sysClkcGetFreq (PAL_SYS_CLKC_ARM) / 8; break; case avm_clock_id_tdm: clk = PAL_sysClkcGetFreq (PAL_SYS_CLKC_TDM); break; default: PRINTK(KERN_ERR"puma_get_clock: unknown id=%d\n", clock_id); break; } DBG_TRC("puma_get_clock: %s %u %cHz\n", puma_name_clock_id(clock_id), puma_norm_clock(clk, 0), puma_norm_clock(clk, 1)); return clk; } EXPORT_SYMBOL(puma_get_clock); /*------------------------------------------------------------------------------------------*\ \*------------------------------------------------------------------------------------------*/ unsigned int puma_set_clock(enum _avm_clock_id clock_id, unsigned int clk) { switch(clock_id) { case avm_clock_id_cpu: return update_sysclk_divisor( 400000000 / clk); /*--- return set_sysclk_freq(PAL_SYS_CLKC_ARM, clk); ---*/ case avm_clock_id_system: /*--- return PAL_sysClkcSetFreq (PAL_SYS_CLKC_SYSCLK2, clk); ---*/ case avm_clock_id_usb: /*--- return PAL_sysClkcSetFreq (PAL_SYS_CLKC_USB, clk); ---*/ case avm_clock_id_docsis: /*--- return PAL_sysClkcSetFreq (PAL_SYS_CLKC_DOCSIS, clk); ---*/ case avm_clock_id_gmii: /*--- return PAL_sysClkcSetFreq (PAL_SYS_CLKC_GMII, clk); ---*/ case avm_clock_id_vlynq: case avm_clock_id_vbus: /*--- return PAL_sysClkcSetFreq (PAL_SYS_CLKC_VLYNQ, clk); ---*/ default: PRINTK(KERN_ERR"puma_set_clock: unknown id=%d\n", clock_id); return -1; } } EXPORT_SYMBOL(puma_set_clock);