Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

powerpc/405ex: provide necessary fixup function to support cuImage

For cuImage format it's necessary to provide clock fixups since u-boot will
not pass necessary clock frequency into the dtb included into cuImage so we
implement the clock fixups as defined in the technical documentation for the
board and update header file with the basic register definitions.

Signed-off-by: Tiejun Chen <tiejun.chen@windriver.com>
Signed-off-by: Josh Boyer <jwboyer@linux.vnet.ibm.com>

authored by

Tiejun Chen and committed by
Josh Boyer
0484c1df 0cdf50a7

+144 -3
+142
arch/powerpc/boot/4xx.c
··· 8 8 * Eugene Surovegin <eugene.surovegin@zultys.com> or <ebs@ebshome.net> 9 9 * Copyright (c) 2003, 2004 Zultys Technologies 10 10 * 11 + * Copyright (C) 2009 Wind River Systems, Inc. 12 + * Updated for supporting PPC405EX on Kilauea. 13 + * Tiejun Chen <tiejun.chen@windriver.com> 14 + * 11 15 * This program is free software; you can redistribute it and/or 12 16 * modify it under the terms of the GNU General Public License 13 17 * as published by the Free Software Foundation; either version ··· 662 658 dt_fixup_clock("/plb/ebc", ebc); 663 659 dt_fixup_clock("/plb/opb/serial@ef600300", uart0); 664 660 dt_fixup_clock("/plb/opb/serial@ef600400", uart1); 661 + } 662 + 663 + static u8 ibm405ex_fwdv_multi_bits[] = { 664 + /* values for: 1 - 16 */ 665 + 0x01, 0x02, 0x0e, 0x09, 0x04, 0x0b, 0x10, 0x0d, 0x0c, 0x05, 666 + 0x06, 0x0f, 0x0a, 0x07, 0x08, 0x03 667 + }; 668 + 669 + u32 ibm405ex_get_fwdva(unsigned long cpr_fwdv) 670 + { 671 + u32 index; 672 + 673 + for (index = 0; index < ARRAY_SIZE(ibm405ex_fwdv_multi_bits); index++) 674 + if (cpr_fwdv == (u32)ibm405ex_fwdv_multi_bits[index]) 675 + return index + 1; 676 + 677 + return 0; 678 + } 679 + 680 + static u8 ibm405ex_fbdv_multi_bits[] = { 681 + /* values for: 1 - 100 */ 682 + 0x00, 0xff, 0x7e, 0xfd, 0x7a, 0xf5, 0x6a, 0xd5, 0x2a, 0xd4, 683 + 0x29, 0xd3, 0x26, 0xcc, 0x19, 0xb3, 0x67, 0xce, 0x1d, 0xbb, 684 + 0x77, 0xee, 0x5d, 0xba, 0x74, 0xe9, 0x52, 0xa5, 0x4b, 0x96, 685 + 0x2c, 0xd8, 0x31, 0xe3, 0x46, 0x8d, 0x1b, 0xb7, 0x6f, 0xde, 686 + 0x3d, 0xfb, 0x76, 0xed, 0x5a, 0xb5, 0x6b, 0xd6, 0x2d, 0xdb, 687 + 0x36, 0xec, 0x59, 0xb2, 0x64, 0xc9, 0x12, 0xa4, 0x48, 0x91, 688 + 0x23, 0xc7, 0x0e, 0x9c, 0x38, 0xf0, 0x61, 0xc2, 0x05, 0x8b, 689 + 0x17, 0xaf, 0x5f, 0xbe, 0x7c, 0xf9, 0x72, 0xe5, 0x4a, 0x95, 690 + 0x2b, 0xd7, 0x2e, 0xdc, 0x39, 0xf3, 0x66, 0xcd, 0x1a, 0xb4, 691 + 0x68, 0xd1, 0x22, 0xc4, 0x09, 0x93, 0x27, 0xcf, 0x1e, 0xbc, 692 + /* values for: 101 - 200 */ 693 + 0x78, 0xf1, 0x62, 0xc5, 0x0a, 0x94, 0x28, 0xd0, 0x21, 0xc3, 694 + 0x06, 0x8c, 0x18, 0xb0, 0x60, 0xc1, 0x02, 0x84, 0x08, 0x90, 695 + 0x20, 0xc0, 0x01, 0x83, 0x07, 0x8f, 0x1f, 0xbf, 0x7f, 0xfe, 696 + 0x7d, 0xfa, 0x75, 0xea, 0x55, 0xaa, 0x54, 0xa9, 0x53, 0xa6, 697 + 0x4c, 0x99, 0x33, 0xe7, 0x4e, 0x9d, 0x3b, 0xf7, 0x6e, 0xdd, 698 + 0x3a, 0xf4, 0x69, 0xd2, 0x25, 0xcb, 0x16, 0xac, 0x58, 0xb1, 699 + 0x63, 0xc6, 0x0d, 0x9b, 0x37, 0xef, 0x5e, 0xbd, 0x7b, 0xf6, 700 + 0x6d, 0xda, 0x35, 0xeb, 0x56, 0xad, 0x5b, 0xb6, 0x6c, 0xd9, 701 + 0x32, 0xe4, 0x49, 0x92, 0x24, 0xc8, 0x11, 0xa3, 0x47, 0x8e, 702 + 0x1c, 0xb8, 0x70, 0xe1, 0x42, 0x85, 0x0b, 0x97, 0x2f, 0xdf, 703 + /* values for: 201 - 255 */ 704 + 0x3e, 0xfc, 0x79, 0xf2, 0x65, 0xca, 0x15, 0xab, 0x57, 0xae, 705 + 0x5c, 0xb9, 0x73, 0xe6, 0x4d, 0x9a, 0x34, 0xe8, 0x51, 0xa2, 706 + 0x44, 0x89, 0x13, 0xa7, 0x4f, 0x9e, 0x3c, 0xf8, 0x71, 0xe2, 707 + 0x45, 0x8a, 0x14, 0xa8, 0x50, 0xa1, 0x43, 0x86, 0x0c, 0x98, 708 + 0x30, 0xe0, 0x41, 0x82, 0x04, 0x88, 0x10, 0xa0, 0x40, 0x81, 709 + 0x03, 0x87, 0x0f, 0x9f, 0x3f /* END */ 710 + }; 711 + 712 + u32 ibm405ex_get_fbdv(unsigned long cpr_fbdv) 713 + { 714 + u32 index; 715 + 716 + for (index = 0; index < ARRAY_SIZE(ibm405ex_fbdv_multi_bits); index++) 717 + if (cpr_fbdv == (u32)ibm405ex_fbdv_multi_bits[index]) 718 + return index + 1; 719 + 720 + return 0; 721 + } 722 + 723 + void ibm405ex_fixup_clocks(unsigned int sys_clk, unsigned int uart_clk) 724 + { 725 + /* PLL config */ 726 + u32 pllc = CPR0_READ(DCRN_CPR0_PLLC); 727 + u32 plld = CPR0_READ(DCRN_CPR0_PLLD); 728 + u32 cpud = CPR0_READ(DCRN_CPR0_PRIMAD); 729 + u32 plbd = CPR0_READ(DCRN_CPR0_PRIMBD); 730 + u32 opbd = CPR0_READ(DCRN_CPR0_OPBD); 731 + u32 perd = CPR0_READ(DCRN_CPR0_PERD); 732 + 733 + /* Dividers */ 734 + u32 fbdv = ibm405ex_get_fbdv(__fix_zero((plld >> 24) & 0xff, 1)); 735 + 736 + u32 fwdva = ibm405ex_get_fwdva(__fix_zero((plld >> 16) & 0x0f, 1)); 737 + 738 + u32 cpudv0 = __fix_zero((cpud >> 24) & 7, 8); 739 + 740 + /* PLBDV0 is hardwared to 010. */ 741 + u32 plbdv0 = 2; 742 + u32 plb2xdv0 = __fix_zero((plbd >> 16) & 7, 8); 743 + 744 + u32 opbdv0 = __fix_zero((opbd >> 24) & 3, 4); 745 + 746 + u32 perdv0 = __fix_zero((perd >> 24) & 3, 4); 747 + 748 + /* Resulting clocks */ 749 + u32 cpu, plb, opb, ebc, vco, tb, uart0, uart1; 750 + 751 + /* PLL's VCO is the source for primary forward ? */ 752 + if (pllc & 0x40000000) { 753 + u32 m; 754 + 755 + /* Feedback path */ 756 + switch ((pllc >> 24) & 7) { 757 + case 0: 758 + /* PLLOUTx */ 759 + m = fbdv; 760 + break; 761 + case 1: 762 + /* CPU */ 763 + m = fbdv * fwdva * cpudv0; 764 + break; 765 + case 5: 766 + /* PERClk */ 767 + m = fbdv * fwdva * plb2xdv0 * plbdv0 * opbdv0 * perdv0; 768 + break; 769 + default: 770 + printf("WARNING ! Invalid PLL feedback source !\n"); 771 + goto bypass; 772 + } 773 + 774 + vco = (unsigned int)(sys_clk * m); 775 + } else { 776 + bypass: 777 + /* Bypass system PLL */ 778 + vco = 0; 779 + } 780 + 781 + /* CPU = VCO / ( FWDVA x CPUDV0) */ 782 + cpu = vco / (fwdva * cpudv0); 783 + /* PLB = VCO / ( FWDVA x PLB2XDV0 x PLBDV0) */ 784 + plb = vco / (fwdva * plb2xdv0 * plbdv0); 785 + /* OPB = PLB / OPBDV0 */ 786 + opb = plb / opbdv0; 787 + /* EBC = OPB / PERDV0 */ 788 + ebc = opb / perdv0; 789 + 790 + tb = cpu; 791 + uart0 = uart1 = uart_clk; 792 + 793 + dt_fixup_cpu_clocks(cpu, tb, 0); 794 + dt_fixup_clock("/plb", plb); 795 + dt_fixup_clock("/plb/opb", opb); 796 + dt_fixup_clock("/plb/opb/ebc", ebc); 797 + dt_fixup_clock("/plb/opb/serial@ef600200", uart0); 798 + dt_fixup_clock("/plb/opb/serial@ef600300", uart1); 665 799 }
+1
arch/powerpc/boot/4xx.h
··· 21 21 22 22 void ibm405gp_fixup_clocks(unsigned int sys_clk, unsigned int ser_clk); 23 23 void ibm405ep_fixup_clocks(unsigned int sys_clk); 24 + void ibm405ex_fixup_clocks(unsigned int sys_clk, unsigned int uart_clk); 24 25 void ibm440gp_fixup_clocks(unsigned int sys_clk, unsigned int ser_clk); 25 26 void ibm440ep_fixup_clocks(unsigned int sys_clk, unsigned int ser_clk, 26 27 unsigned int tmr_clk);
+1 -3
arch/powerpc/boot/dcr.h
··· 153 153 #define DCRN_CPC0_PLLMR1 0xf4 154 154 #define DCRN_CPC0_UCR 0xf5 155 155 156 - /* 440GX Clock control etc */ 157 - 158 - 156 + /* 440GX/405EX Clock Control reg */ 159 157 #define DCRN_CPR0_CLKUPD 0x020 160 158 #define DCRN_CPR0_PLLC 0x040 161 159 #define DCRN_CPR0_PLLD 0x060