19865853851313e0d94a4acde42d6f9d8070bb376Li Yang/* 29865853851313e0d94a4acde42d6f9d8070bb376Li Yang * arch/powerpc/sysdev/qe_lib/ucc.c 39865853851313e0d94a4acde42d6f9d8070bb376Li Yang * 49865853851313e0d94a4acde42d6f9d8070bb376Li Yang * QE UCC API Set - UCC specific routines implementations. 59865853851313e0d94a4acde42d6f9d8070bb376Li Yang * 68a56e1ee9229ef1c5c558b53f696af9152024a15Yang Li * Copyright (C) 2006 Freescale Semiconductor, Inc. All rights reserved. 79865853851313e0d94a4acde42d6f9d8070bb376Li Yang * 89865853851313e0d94a4acde42d6f9d8070bb376Li Yang * Authors: Shlomi Gridish <gridish@freescale.com> 99865853851313e0d94a4acde42d6f9d8070bb376Li Yang * Li Yang <leoli@freescale.com> 109865853851313e0d94a4acde42d6f9d8070bb376Li Yang * 119865853851313e0d94a4acde42d6f9d8070bb376Li Yang * This program is free software; you can redistribute it and/or modify it 129865853851313e0d94a4acde42d6f9d8070bb376Li Yang * under the terms of the GNU General Public License as published by the 139865853851313e0d94a4acde42d6f9d8070bb376Li Yang * Free Software Foundation; either version 2 of the License, or (at your 149865853851313e0d94a4acde42d6f9d8070bb376Li Yang * option) any later version. 159865853851313e0d94a4acde42d6f9d8070bb376Li Yang */ 169865853851313e0d94a4acde42d6f9d8070bb376Li Yang#include <linux/kernel.h> 179865853851313e0d94a4acde42d6f9d8070bb376Li Yang#include <linux/errno.h> 189865853851313e0d94a4acde42d6f9d8070bb376Li Yang#include <linux/stddef.h> 1909a3fba8c132a55f153fd65fc1085b717a6193c8Anton Vorontsov#include <linux/spinlock.h> 204b16f8e2d6d64249f0ed3ca7fe2a319d0dde2719Paul Gortmaker#include <linux/export.h> 219865853851313e0d94a4acde42d6f9d8070bb376Li Yang 229865853851313e0d94a4acde42d6f9d8070bb376Li Yang#include <asm/irq.h> 239865853851313e0d94a4acde42d6f9d8070bb376Li Yang#include <asm/io.h> 249865853851313e0d94a4acde42d6f9d8070bb376Li Yang#include <asm/immap_qe.h> 259865853851313e0d94a4acde42d6f9d8070bb376Li Yang#include <asm/qe.h> 269865853851313e0d94a4acde42d6f9d8070bb376Li Yang#include <asm/ucc.h> 279865853851313e0d94a4acde42d6f9d8070bb376Li Yang 286b0b594bb81f86dbc7b0829ee5102abaab242913Timur Tabiint ucc_set_qe_mux_mii_mng(unsigned int ucc_num) 299865853851313e0d94a4acde42d6f9d8070bb376Li Yang{ 309865853851313e0d94a4acde42d6f9d8070bb376Li Yang unsigned long flags; 319865853851313e0d94a4acde42d6f9d8070bb376Li Yang 326b0b594bb81f86dbc7b0829ee5102abaab242913Timur Tabi if (ucc_num > UCC_MAX_NUM - 1) 336b0b594bb81f86dbc7b0829ee5102abaab242913Timur Tabi return -EINVAL; 346b0b594bb81f86dbc7b0829ee5102abaab242913Timur Tabi 355e41486c408eb4206aee09303631427f57771691Anton Vorontsov spin_lock_irqsave(&cmxgcr_lock, flags); 366b0b594bb81f86dbc7b0829ee5102abaab242913Timur Tabi clrsetbits_be32(&qe_immr->qmx.cmxgcr, QE_CMXGCR_MII_ENET_MNG, 376b0b594bb81f86dbc7b0829ee5102abaab242913Timur Tabi ucc_num << QE_CMXGCR_MII_ENET_MNG_SHIFT); 385e41486c408eb4206aee09303631427f57771691Anton Vorontsov spin_unlock_irqrestore(&cmxgcr_lock, flags); 399865853851313e0d94a4acde42d6f9d8070bb376Li Yang 409865853851313e0d94a4acde42d6f9d8070bb376Li Yang return 0; 419865853851313e0d94a4acde42d6f9d8070bb376Li Yang} 4265482ccf9d00bf4f68e17eb9c656d045d26e5d1fLi YangEXPORT_SYMBOL(ucc_set_qe_mux_mii_mng); 439865853851313e0d94a4acde42d6f9d8070bb376Li Yang 446b0b594bb81f86dbc7b0829ee5102abaab242913Timur Tabi/* Configure the UCC to either Slow or Fast. 456b0b594bb81f86dbc7b0829ee5102abaab242913Timur Tabi * 466b0b594bb81f86dbc7b0829ee5102abaab242913Timur Tabi * A given UCC can be figured to support either "slow" devices (e.g. UART) 476b0b594bb81f86dbc7b0829ee5102abaab242913Timur Tabi * or "fast" devices (e.g. Ethernet). 486b0b594bb81f86dbc7b0829ee5102abaab242913Timur Tabi * 496b0b594bb81f86dbc7b0829ee5102abaab242913Timur Tabi * 'ucc_num' is the UCC number, from 0 - 7. 506b0b594bb81f86dbc7b0829ee5102abaab242913Timur Tabi * 516b0b594bb81f86dbc7b0829ee5102abaab242913Timur Tabi * This function also sets the UCC_GUEMR_SET_RESERVED3 bit because that bit 526b0b594bb81f86dbc7b0829ee5102abaab242913Timur Tabi * must always be set to 1. 536b0b594bb81f86dbc7b0829ee5102abaab242913Timur Tabi */ 546b0b594bb81f86dbc7b0829ee5102abaab242913Timur Tabiint ucc_set_type(unsigned int ucc_num, enum ucc_speed_type speed) 559865853851313e0d94a4acde42d6f9d8070bb376Li Yang{ 566b0b594bb81f86dbc7b0829ee5102abaab242913Timur Tabi u8 __iomem *guemr; 579865853851313e0d94a4acde42d6f9d8070bb376Li Yang 586b0b594bb81f86dbc7b0829ee5102abaab242913Timur Tabi /* The GUEMR register is at the same location for both slow and fast 596b0b594bb81f86dbc7b0829ee5102abaab242913Timur Tabi devices, so we just use uccX.slow.guemr. */ 609865853851313e0d94a4acde42d6f9d8070bb376Li Yang switch (ucc_num) { 616b0b594bb81f86dbc7b0829ee5102abaab242913Timur Tabi case 0: guemr = &qe_immr->ucc1.slow.guemr; 629865853851313e0d94a4acde42d6f9d8070bb376Li Yang break; 636b0b594bb81f86dbc7b0829ee5102abaab242913Timur Tabi case 1: guemr = &qe_immr->ucc2.slow.guemr; 649865853851313e0d94a4acde42d6f9d8070bb376Li Yang break; 656b0b594bb81f86dbc7b0829ee5102abaab242913Timur Tabi case 2: guemr = &qe_immr->ucc3.slow.guemr; 669865853851313e0d94a4acde42d6f9d8070bb376Li Yang break; 676b0b594bb81f86dbc7b0829ee5102abaab242913Timur Tabi case 3: guemr = &qe_immr->ucc4.slow.guemr; 689865853851313e0d94a4acde42d6f9d8070bb376Li Yang break; 696b0b594bb81f86dbc7b0829ee5102abaab242913Timur Tabi case 4: guemr = &qe_immr->ucc5.slow.guemr; 709865853851313e0d94a4acde42d6f9d8070bb376Li Yang break; 716b0b594bb81f86dbc7b0829ee5102abaab242913Timur Tabi case 5: guemr = &qe_immr->ucc6.slow.guemr; 729865853851313e0d94a4acde42d6f9d8070bb376Li Yang break; 736b0b594bb81f86dbc7b0829ee5102abaab242913Timur Tabi case 6: guemr = &qe_immr->ucc7.slow.guemr; 749865853851313e0d94a4acde42d6f9d8070bb376Li Yang break; 756b0b594bb81f86dbc7b0829ee5102abaab242913Timur Tabi case 7: guemr = &qe_immr->ucc8.slow.guemr; 769865853851313e0d94a4acde42d6f9d8070bb376Li Yang break; 779865853851313e0d94a4acde42d6f9d8070bb376Li Yang default: 786b0b594bb81f86dbc7b0829ee5102abaab242913Timur Tabi return -EINVAL; 799865853851313e0d94a4acde42d6f9d8070bb376Li Yang } 806b0b594bb81f86dbc7b0829ee5102abaab242913Timur Tabi 816b0b594bb81f86dbc7b0829ee5102abaab242913Timur Tabi clrsetbits_8(guemr, UCC_GUEMR_MODE_MASK, 826b0b594bb81f86dbc7b0829ee5102abaab242913Timur Tabi UCC_GUEMR_SET_RESERVED3 | speed); 836b0b594bb81f86dbc7b0829ee5102abaab242913Timur Tabi 846b0b594bb81f86dbc7b0829ee5102abaab242913Timur Tabi return 0; 856b0b594bb81f86dbc7b0829ee5102abaab242913Timur Tabi} 866b0b594bb81f86dbc7b0829ee5102abaab242913Timur Tabi 877e1cc9c55a2a4af62f30fade62fb612a243def39Andy Flemingstatic void get_cmxucr_reg(unsigned int ucc_num, __be32 __iomem **cmxucr, 886b0b594bb81f86dbc7b0829ee5102abaab242913Timur Tabi unsigned int *reg_num, unsigned int *shift) 896b0b594bb81f86dbc7b0829ee5102abaab242913Timur Tabi{ 906b0b594bb81f86dbc7b0829ee5102abaab242913Timur Tabi unsigned int cmx = ((ucc_num & 1) << 1) + (ucc_num > 3); 916b0b594bb81f86dbc7b0829ee5102abaab242913Timur Tabi 926b0b594bb81f86dbc7b0829ee5102abaab242913Timur Tabi *reg_num = cmx + 1; 936b0b594bb81f86dbc7b0829ee5102abaab242913Timur Tabi *cmxucr = &qe_immr->qmx.cmxucr[cmx]; 946b0b594bb81f86dbc7b0829ee5102abaab242913Timur Tabi *shift = 16 - 8 * (ucc_num & 2); 959865853851313e0d94a4acde42d6f9d8070bb376Li Yang} 969865853851313e0d94a4acde42d6f9d8070bb376Li Yang 976b0b594bb81f86dbc7b0829ee5102abaab242913Timur Tabiint ucc_mux_set_grant_tsa_bkpt(unsigned int ucc_num, int set, u32 mask) 989865853851313e0d94a4acde42d6f9d8070bb376Li Yang{ 997e1cc9c55a2a4af62f30fade62fb612a243def39Andy Fleming __be32 __iomem *cmxucr; 1006b0b594bb81f86dbc7b0829ee5102abaab242913Timur Tabi unsigned int reg_num; 1016b0b594bb81f86dbc7b0829ee5102abaab242913Timur Tabi unsigned int shift; 1029865853851313e0d94a4acde42d6f9d8070bb376Li Yang 1039865853851313e0d94a4acde42d6f9d8070bb376Li Yang /* check if the UCC number is in range. */ 1046b0b594bb81f86dbc7b0829ee5102abaab242913Timur Tabi if (ucc_num > UCC_MAX_NUM - 1) 1059865853851313e0d94a4acde42d6f9d8070bb376Li Yang return -EINVAL; 1069865853851313e0d94a4acde42d6f9d8070bb376Li Yang 1076b0b594bb81f86dbc7b0829ee5102abaab242913Timur Tabi get_cmxucr_reg(ucc_num, &cmxucr, ®_num, &shift); 1089865853851313e0d94a4acde42d6f9d8070bb376Li Yang 1099865853851313e0d94a4acde42d6f9d8070bb376Li Yang if (set) 1106b0b594bb81f86dbc7b0829ee5102abaab242913Timur Tabi setbits32(cmxucr, mask << shift); 1119865853851313e0d94a4acde42d6f9d8070bb376Li Yang else 1126b0b594bb81f86dbc7b0829ee5102abaab242913Timur Tabi clrbits32(cmxucr, mask << shift); 1139865853851313e0d94a4acde42d6f9d8070bb376Li Yang 1149865853851313e0d94a4acde42d6f9d8070bb376Li Yang return 0; 1159865853851313e0d94a4acde42d6f9d8070bb376Li Yang} 1169865853851313e0d94a4acde42d6f9d8070bb376Li Yang 1176b0b594bb81f86dbc7b0829ee5102abaab242913Timur Tabiint ucc_set_qe_mux_rxtx(unsigned int ucc_num, enum qe_clock clock, 1186b0b594bb81f86dbc7b0829ee5102abaab242913Timur Tabi enum comm_dir mode) 1199865853851313e0d94a4acde42d6f9d8070bb376Li Yang{ 1207e1cc9c55a2a4af62f30fade62fb612a243def39Andy Fleming __be32 __iomem *cmxucr; 1216b0b594bb81f86dbc7b0829ee5102abaab242913Timur Tabi unsigned int reg_num; 1226b0b594bb81f86dbc7b0829ee5102abaab242913Timur Tabi unsigned int shift; 1236b0b594bb81f86dbc7b0829ee5102abaab242913Timur Tabi u32 clock_bits = 0; 1249865853851313e0d94a4acde42d6f9d8070bb376Li Yang 1259865853851313e0d94a4acde42d6f9d8070bb376Li Yang /* check if the UCC number is in range. */ 1266b0b594bb81f86dbc7b0829ee5102abaab242913Timur Tabi if (ucc_num > UCC_MAX_NUM - 1) 1279865853851313e0d94a4acde42d6f9d8070bb376Li Yang return -EINVAL; 1289865853851313e0d94a4acde42d6f9d8070bb376Li Yang 1296b0b594bb81f86dbc7b0829ee5102abaab242913Timur Tabi /* The communications direction must be RX or TX */ 1306b0b594bb81f86dbc7b0829ee5102abaab242913Timur Tabi if (!((mode == COMM_DIR_RX) || (mode == COMM_DIR_TX))) 1319865853851313e0d94a4acde42d6f9d8070bb376Li Yang return -EINVAL; 1329865853851313e0d94a4acde42d6f9d8070bb376Li Yang 1336b0b594bb81f86dbc7b0829ee5102abaab242913Timur Tabi get_cmxucr_reg(ucc_num, &cmxucr, ®_num, &shift); 1349865853851313e0d94a4acde42d6f9d8070bb376Li Yang 1359865853851313e0d94a4acde42d6f9d8070bb376Li Yang switch (reg_num) { 1369865853851313e0d94a4acde42d6f9d8070bb376Li Yang case 1: 1379865853851313e0d94a4acde42d6f9d8070bb376Li Yang switch (clock) { 1386b0b594bb81f86dbc7b0829ee5102abaab242913Timur Tabi case QE_BRG1: clock_bits = 1; break; 1396b0b594bb81f86dbc7b0829ee5102abaab242913Timur Tabi case QE_BRG2: clock_bits = 2; break; 1406b0b594bb81f86dbc7b0829ee5102abaab242913Timur Tabi case QE_BRG7: clock_bits = 3; break; 1416b0b594bb81f86dbc7b0829ee5102abaab242913Timur Tabi case QE_BRG8: clock_bits = 4; break; 1426b0b594bb81f86dbc7b0829ee5102abaab242913Timur Tabi case QE_CLK9: clock_bits = 5; break; 1436b0b594bb81f86dbc7b0829ee5102abaab242913Timur Tabi case QE_CLK10: clock_bits = 6; break; 1446b0b594bb81f86dbc7b0829ee5102abaab242913Timur Tabi case QE_CLK11: clock_bits = 7; break; 1456b0b594bb81f86dbc7b0829ee5102abaab242913Timur Tabi case QE_CLK12: clock_bits = 8; break; 1466b0b594bb81f86dbc7b0829ee5102abaab242913Timur Tabi case QE_CLK15: clock_bits = 9; break; 1476b0b594bb81f86dbc7b0829ee5102abaab242913Timur Tabi case QE_CLK16: clock_bits = 10; break; 1486b0b594bb81f86dbc7b0829ee5102abaab242913Timur Tabi default: break; 1499865853851313e0d94a4acde42d6f9d8070bb376Li Yang } 1509865853851313e0d94a4acde42d6f9d8070bb376Li Yang break; 1519865853851313e0d94a4acde42d6f9d8070bb376Li Yang case 2: 1529865853851313e0d94a4acde42d6f9d8070bb376Li Yang switch (clock) { 1536b0b594bb81f86dbc7b0829ee5102abaab242913Timur Tabi case QE_BRG5: clock_bits = 1; break; 1546b0b594bb81f86dbc7b0829ee5102abaab242913Timur Tabi case QE_BRG6: clock_bits = 2; break; 1556b0b594bb81f86dbc7b0829ee5102abaab242913Timur Tabi case QE_BRG7: clock_bits = 3; break; 1566b0b594bb81f86dbc7b0829ee5102abaab242913Timur Tabi case QE_BRG8: clock_bits = 4; break; 1576b0b594bb81f86dbc7b0829ee5102abaab242913Timur Tabi case QE_CLK13: clock_bits = 5; break; 1586b0b594bb81f86dbc7b0829ee5102abaab242913Timur Tabi case QE_CLK14: clock_bits = 6; break; 1596b0b594bb81f86dbc7b0829ee5102abaab242913Timur Tabi case QE_CLK19: clock_bits = 7; break; 1606b0b594bb81f86dbc7b0829ee5102abaab242913Timur Tabi case QE_CLK20: clock_bits = 8; break; 1616b0b594bb81f86dbc7b0829ee5102abaab242913Timur Tabi case QE_CLK15: clock_bits = 9; break; 1626b0b594bb81f86dbc7b0829ee5102abaab242913Timur Tabi case QE_CLK16: clock_bits = 10; break; 1636b0b594bb81f86dbc7b0829ee5102abaab242913Timur Tabi default: break; 1649865853851313e0d94a4acde42d6f9d8070bb376Li Yang } 1659865853851313e0d94a4acde42d6f9d8070bb376Li Yang break; 1669865853851313e0d94a4acde42d6f9d8070bb376Li Yang case 3: 1679865853851313e0d94a4acde42d6f9d8070bb376Li Yang switch (clock) { 1686b0b594bb81f86dbc7b0829ee5102abaab242913Timur Tabi case QE_BRG9: clock_bits = 1; break; 1696b0b594bb81f86dbc7b0829ee5102abaab242913Timur Tabi case QE_BRG10: clock_bits = 2; break; 1706b0b594bb81f86dbc7b0829ee5102abaab242913Timur Tabi case QE_BRG15: clock_bits = 3; break; 1716b0b594bb81f86dbc7b0829ee5102abaab242913Timur Tabi case QE_BRG16: clock_bits = 4; break; 1726b0b594bb81f86dbc7b0829ee5102abaab242913Timur Tabi case QE_CLK3: clock_bits = 5; break; 1736b0b594bb81f86dbc7b0829ee5102abaab242913Timur Tabi case QE_CLK4: clock_bits = 6; break; 1746b0b594bb81f86dbc7b0829ee5102abaab242913Timur Tabi case QE_CLK17: clock_bits = 7; break; 1756b0b594bb81f86dbc7b0829ee5102abaab242913Timur Tabi case QE_CLK18: clock_bits = 8; break; 1766b0b594bb81f86dbc7b0829ee5102abaab242913Timur Tabi case QE_CLK7: clock_bits = 9; break; 1776b0b594bb81f86dbc7b0829ee5102abaab242913Timur Tabi case QE_CLK8: clock_bits = 10; break; 1786b0b594bb81f86dbc7b0829ee5102abaab242913Timur Tabi case QE_CLK16: clock_bits = 11; break; 1796b0b594bb81f86dbc7b0829ee5102abaab242913Timur Tabi default: break; 1809865853851313e0d94a4acde42d6f9d8070bb376Li Yang } 1819865853851313e0d94a4acde42d6f9d8070bb376Li Yang break; 1829865853851313e0d94a4acde42d6f9d8070bb376Li Yang case 4: 1839865853851313e0d94a4acde42d6f9d8070bb376Li Yang switch (clock) { 1846b0b594bb81f86dbc7b0829ee5102abaab242913Timur Tabi case QE_BRG13: clock_bits = 1; break; 1856b0b594bb81f86dbc7b0829ee5102abaab242913Timur Tabi case QE_BRG14: clock_bits = 2; break; 1866b0b594bb81f86dbc7b0829ee5102abaab242913Timur Tabi case QE_BRG15: clock_bits = 3; break; 1876b0b594bb81f86dbc7b0829ee5102abaab242913Timur Tabi case QE_BRG16: clock_bits = 4; break; 1886b0b594bb81f86dbc7b0829ee5102abaab242913Timur Tabi case QE_CLK5: clock_bits = 5; break; 1896b0b594bb81f86dbc7b0829ee5102abaab242913Timur Tabi case QE_CLK6: clock_bits = 6; break; 1906b0b594bb81f86dbc7b0829ee5102abaab242913Timur Tabi case QE_CLK21: clock_bits = 7; break; 1916b0b594bb81f86dbc7b0829ee5102abaab242913Timur Tabi case QE_CLK22: clock_bits = 8; break; 1926b0b594bb81f86dbc7b0829ee5102abaab242913Timur Tabi case QE_CLK7: clock_bits = 9; break; 1936b0b594bb81f86dbc7b0829ee5102abaab242913Timur Tabi case QE_CLK8: clock_bits = 10; break; 1946b0b594bb81f86dbc7b0829ee5102abaab242913Timur Tabi case QE_CLK16: clock_bits = 11; break; 1956b0b594bb81f86dbc7b0829ee5102abaab242913Timur Tabi default: break; 1969865853851313e0d94a4acde42d6f9d8070bb376Li Yang } 1979865853851313e0d94a4acde42d6f9d8070bb376Li Yang break; 1986b0b594bb81f86dbc7b0829ee5102abaab242913Timur Tabi default: break; 1999865853851313e0d94a4acde42d6f9d8070bb376Li Yang } 2009865853851313e0d94a4acde42d6f9d8070bb376Li Yang 2016b0b594bb81f86dbc7b0829ee5102abaab242913Timur Tabi /* Check for invalid combination of clock and UCC number */ 2026b0b594bb81f86dbc7b0829ee5102abaab242913Timur Tabi if (!clock_bits) 2039865853851313e0d94a4acde42d6f9d8070bb376Li Yang return -ENOENT; 2049865853851313e0d94a4acde42d6f9d8070bb376Li Yang 2056b0b594bb81f86dbc7b0829ee5102abaab242913Timur Tabi if (mode == COMM_DIR_RX) 2066b0b594bb81f86dbc7b0829ee5102abaab242913Timur Tabi shift += 4; 2079865853851313e0d94a4acde42d6f9d8070bb376Li Yang 2086b0b594bb81f86dbc7b0829ee5102abaab242913Timur Tabi clrsetbits_be32(cmxucr, QE_CMXUCR_TX_CLK_SRC_MASK << shift, 2096b0b594bb81f86dbc7b0829ee5102abaab242913Timur Tabi clock_bits << shift); 2109865853851313e0d94a4acde42d6f9d8070bb376Li Yang 2119865853851313e0d94a4acde42d6f9d8070bb376Li Yang return 0; 2129865853851313e0d94a4acde42d6f9d8070bb376Li Yang} 213