18c2ecf20Sopenharmony_ci// SPDX-License-Identifier: GPL-2.0-or-later
28c2ecf20Sopenharmony_ci/*
38c2ecf20Sopenharmony_ci * arch/powerpc/sysdev/qe_lib/ucc.c
48c2ecf20Sopenharmony_ci *
58c2ecf20Sopenharmony_ci * QE UCC API Set - UCC specific routines implementations.
68c2ecf20Sopenharmony_ci *
78c2ecf20Sopenharmony_ci * Copyright (C) 2006 Freescale Semiconductor, Inc. All rights reserved.
88c2ecf20Sopenharmony_ci *
98c2ecf20Sopenharmony_ci * Authors: 	Shlomi Gridish <gridish@freescale.com>
108c2ecf20Sopenharmony_ci * 		Li Yang <leoli@freescale.com>
118c2ecf20Sopenharmony_ci */
128c2ecf20Sopenharmony_ci#include <linux/kernel.h>
138c2ecf20Sopenharmony_ci#include <linux/errno.h>
148c2ecf20Sopenharmony_ci#include <linux/stddef.h>
158c2ecf20Sopenharmony_ci#include <linux/spinlock.h>
168c2ecf20Sopenharmony_ci#include <linux/export.h>
178c2ecf20Sopenharmony_ci
188c2ecf20Sopenharmony_ci#include <asm/io.h>
198c2ecf20Sopenharmony_ci#include <soc/fsl/qe/immap_qe.h>
208c2ecf20Sopenharmony_ci#include <soc/fsl/qe/qe.h>
218c2ecf20Sopenharmony_ci#include <soc/fsl/qe/ucc.h>
228c2ecf20Sopenharmony_ci
238c2ecf20Sopenharmony_ci#define UCC_TDM_NUM 8
248c2ecf20Sopenharmony_ci#define RX_SYNC_SHIFT_BASE 30
258c2ecf20Sopenharmony_ci#define TX_SYNC_SHIFT_BASE 14
268c2ecf20Sopenharmony_ci#define RX_CLK_SHIFT_BASE 28
278c2ecf20Sopenharmony_ci#define TX_CLK_SHIFT_BASE 12
288c2ecf20Sopenharmony_ci
298c2ecf20Sopenharmony_ciint ucc_set_qe_mux_mii_mng(unsigned int ucc_num)
308c2ecf20Sopenharmony_ci{
318c2ecf20Sopenharmony_ci	unsigned long flags;
328c2ecf20Sopenharmony_ci
338c2ecf20Sopenharmony_ci	if (ucc_num > UCC_MAX_NUM - 1)
348c2ecf20Sopenharmony_ci		return -EINVAL;
358c2ecf20Sopenharmony_ci
368c2ecf20Sopenharmony_ci	spin_lock_irqsave(&cmxgcr_lock, flags);
378c2ecf20Sopenharmony_ci	qe_clrsetbits_be32(&qe_immr->qmx.cmxgcr, QE_CMXGCR_MII_ENET_MNG,
388c2ecf20Sopenharmony_ci			   ucc_num << QE_CMXGCR_MII_ENET_MNG_SHIFT);
398c2ecf20Sopenharmony_ci	spin_unlock_irqrestore(&cmxgcr_lock, flags);
408c2ecf20Sopenharmony_ci
418c2ecf20Sopenharmony_ci	return 0;
428c2ecf20Sopenharmony_ci}
438c2ecf20Sopenharmony_ciEXPORT_SYMBOL(ucc_set_qe_mux_mii_mng);
448c2ecf20Sopenharmony_ci
458c2ecf20Sopenharmony_ci/* Configure the UCC to either Slow or Fast.
468c2ecf20Sopenharmony_ci *
478c2ecf20Sopenharmony_ci * A given UCC can be figured to support either "slow" devices (e.g. UART)
488c2ecf20Sopenharmony_ci * or "fast" devices (e.g. Ethernet).
498c2ecf20Sopenharmony_ci *
508c2ecf20Sopenharmony_ci * 'ucc_num' is the UCC number, from 0 - 7.
518c2ecf20Sopenharmony_ci *
528c2ecf20Sopenharmony_ci * This function also sets the UCC_GUEMR_SET_RESERVED3 bit because that bit
538c2ecf20Sopenharmony_ci * must always be set to 1.
548c2ecf20Sopenharmony_ci */
558c2ecf20Sopenharmony_ciint ucc_set_type(unsigned int ucc_num, enum ucc_speed_type speed)
568c2ecf20Sopenharmony_ci{
578c2ecf20Sopenharmony_ci	u8 __iomem *guemr;
588c2ecf20Sopenharmony_ci
598c2ecf20Sopenharmony_ci	/* The GUEMR register is at the same location for both slow and fast
608c2ecf20Sopenharmony_ci	   devices, so we just use uccX.slow.guemr. */
618c2ecf20Sopenharmony_ci	switch (ucc_num) {
628c2ecf20Sopenharmony_ci	case 0: guemr = &qe_immr->ucc1.slow.guemr;
638c2ecf20Sopenharmony_ci		break;
648c2ecf20Sopenharmony_ci	case 1: guemr = &qe_immr->ucc2.slow.guemr;
658c2ecf20Sopenharmony_ci		break;
668c2ecf20Sopenharmony_ci	case 2: guemr = &qe_immr->ucc3.slow.guemr;
678c2ecf20Sopenharmony_ci		break;
688c2ecf20Sopenharmony_ci	case 3: guemr = &qe_immr->ucc4.slow.guemr;
698c2ecf20Sopenharmony_ci		break;
708c2ecf20Sopenharmony_ci	case 4: guemr = &qe_immr->ucc5.slow.guemr;
718c2ecf20Sopenharmony_ci		break;
728c2ecf20Sopenharmony_ci	case 5: guemr = &qe_immr->ucc6.slow.guemr;
738c2ecf20Sopenharmony_ci		break;
748c2ecf20Sopenharmony_ci	case 6: guemr = &qe_immr->ucc7.slow.guemr;
758c2ecf20Sopenharmony_ci		break;
768c2ecf20Sopenharmony_ci	case 7: guemr = &qe_immr->ucc8.slow.guemr;
778c2ecf20Sopenharmony_ci		break;
788c2ecf20Sopenharmony_ci	default:
798c2ecf20Sopenharmony_ci		return -EINVAL;
808c2ecf20Sopenharmony_ci	}
818c2ecf20Sopenharmony_ci
828c2ecf20Sopenharmony_ci	qe_clrsetbits_8(guemr, UCC_GUEMR_MODE_MASK,
838c2ecf20Sopenharmony_ci			UCC_GUEMR_SET_RESERVED3 | speed);
848c2ecf20Sopenharmony_ci
858c2ecf20Sopenharmony_ci	return 0;
868c2ecf20Sopenharmony_ci}
878c2ecf20Sopenharmony_ci
888c2ecf20Sopenharmony_cistatic void get_cmxucr_reg(unsigned int ucc_num, __be32 __iomem **cmxucr,
898c2ecf20Sopenharmony_ci	unsigned int *reg_num, unsigned int *shift)
908c2ecf20Sopenharmony_ci{
918c2ecf20Sopenharmony_ci	unsigned int cmx = ((ucc_num & 1) << 1) + (ucc_num > 3);
928c2ecf20Sopenharmony_ci
938c2ecf20Sopenharmony_ci	*reg_num = cmx + 1;
948c2ecf20Sopenharmony_ci	*cmxucr = &qe_immr->qmx.cmxucr[cmx];
958c2ecf20Sopenharmony_ci	*shift = 16 - 8 * (ucc_num & 2);
968c2ecf20Sopenharmony_ci}
978c2ecf20Sopenharmony_ci
988c2ecf20Sopenharmony_ciint ucc_mux_set_grant_tsa_bkpt(unsigned int ucc_num, int set, u32 mask)
998c2ecf20Sopenharmony_ci{
1008c2ecf20Sopenharmony_ci	__be32 __iomem *cmxucr;
1018c2ecf20Sopenharmony_ci	unsigned int reg_num;
1028c2ecf20Sopenharmony_ci	unsigned int shift;
1038c2ecf20Sopenharmony_ci
1048c2ecf20Sopenharmony_ci	/* check if the UCC number is in range. */
1058c2ecf20Sopenharmony_ci	if (ucc_num > UCC_MAX_NUM - 1)
1068c2ecf20Sopenharmony_ci		return -EINVAL;
1078c2ecf20Sopenharmony_ci
1088c2ecf20Sopenharmony_ci	get_cmxucr_reg(ucc_num, &cmxucr, &reg_num, &shift);
1098c2ecf20Sopenharmony_ci
1108c2ecf20Sopenharmony_ci	if (set)
1118c2ecf20Sopenharmony_ci		qe_setbits_be32(cmxucr, mask << shift);
1128c2ecf20Sopenharmony_ci	else
1138c2ecf20Sopenharmony_ci		qe_clrbits_be32(cmxucr, mask << shift);
1148c2ecf20Sopenharmony_ci
1158c2ecf20Sopenharmony_ci	return 0;
1168c2ecf20Sopenharmony_ci}
1178c2ecf20Sopenharmony_ci
1188c2ecf20Sopenharmony_ciint ucc_set_qe_mux_rxtx(unsigned int ucc_num, enum qe_clock clock,
1198c2ecf20Sopenharmony_ci	enum comm_dir mode)
1208c2ecf20Sopenharmony_ci{
1218c2ecf20Sopenharmony_ci	__be32 __iomem *cmxucr;
1228c2ecf20Sopenharmony_ci	unsigned int reg_num;
1238c2ecf20Sopenharmony_ci	unsigned int shift;
1248c2ecf20Sopenharmony_ci	u32 clock_bits = 0;
1258c2ecf20Sopenharmony_ci
1268c2ecf20Sopenharmony_ci	/* check if the UCC number is in range. */
1278c2ecf20Sopenharmony_ci	if (ucc_num > UCC_MAX_NUM - 1)
1288c2ecf20Sopenharmony_ci		return -EINVAL;
1298c2ecf20Sopenharmony_ci
1308c2ecf20Sopenharmony_ci	/* The communications direction must be RX or TX */
1318c2ecf20Sopenharmony_ci	if (!((mode == COMM_DIR_RX) || (mode == COMM_DIR_TX)))
1328c2ecf20Sopenharmony_ci		return -EINVAL;
1338c2ecf20Sopenharmony_ci
1348c2ecf20Sopenharmony_ci	get_cmxucr_reg(ucc_num, &cmxucr, &reg_num, &shift);
1358c2ecf20Sopenharmony_ci
1368c2ecf20Sopenharmony_ci	switch (reg_num) {
1378c2ecf20Sopenharmony_ci	case 1:
1388c2ecf20Sopenharmony_ci		switch (clock) {
1398c2ecf20Sopenharmony_ci		case QE_BRG1:	clock_bits = 1; break;
1408c2ecf20Sopenharmony_ci		case QE_BRG2:	clock_bits = 2; break;
1418c2ecf20Sopenharmony_ci		case QE_BRG7:	clock_bits = 3; break;
1428c2ecf20Sopenharmony_ci		case QE_BRG8:	clock_bits = 4; break;
1438c2ecf20Sopenharmony_ci		case QE_CLK9:	clock_bits = 5; break;
1448c2ecf20Sopenharmony_ci		case QE_CLK10:	clock_bits = 6; break;
1458c2ecf20Sopenharmony_ci		case QE_CLK11:	clock_bits = 7; break;
1468c2ecf20Sopenharmony_ci		case QE_CLK12:	clock_bits = 8; break;
1478c2ecf20Sopenharmony_ci		case QE_CLK15:	clock_bits = 9; break;
1488c2ecf20Sopenharmony_ci		case QE_CLK16:	clock_bits = 10; break;
1498c2ecf20Sopenharmony_ci		default: break;
1508c2ecf20Sopenharmony_ci		}
1518c2ecf20Sopenharmony_ci		break;
1528c2ecf20Sopenharmony_ci	case 2:
1538c2ecf20Sopenharmony_ci		switch (clock) {
1548c2ecf20Sopenharmony_ci		case QE_BRG5:	clock_bits = 1; break;
1558c2ecf20Sopenharmony_ci		case QE_BRG6:	clock_bits = 2; break;
1568c2ecf20Sopenharmony_ci		case QE_BRG7:	clock_bits = 3; break;
1578c2ecf20Sopenharmony_ci		case QE_BRG8:	clock_bits = 4; break;
1588c2ecf20Sopenharmony_ci		case QE_CLK13:	clock_bits = 5; break;
1598c2ecf20Sopenharmony_ci		case QE_CLK14:	clock_bits = 6; break;
1608c2ecf20Sopenharmony_ci		case QE_CLK19:	clock_bits = 7; break;
1618c2ecf20Sopenharmony_ci		case QE_CLK20:	clock_bits = 8; break;
1628c2ecf20Sopenharmony_ci		case QE_CLK15:	clock_bits = 9; break;
1638c2ecf20Sopenharmony_ci		case QE_CLK16:	clock_bits = 10; break;
1648c2ecf20Sopenharmony_ci		default: break;
1658c2ecf20Sopenharmony_ci		}
1668c2ecf20Sopenharmony_ci		break;
1678c2ecf20Sopenharmony_ci	case 3:
1688c2ecf20Sopenharmony_ci		switch (clock) {
1698c2ecf20Sopenharmony_ci		case QE_BRG9:	clock_bits = 1; break;
1708c2ecf20Sopenharmony_ci		case QE_BRG10:	clock_bits = 2; break;
1718c2ecf20Sopenharmony_ci		case QE_BRG15:	clock_bits = 3; break;
1728c2ecf20Sopenharmony_ci		case QE_BRG16:	clock_bits = 4; break;
1738c2ecf20Sopenharmony_ci		case QE_CLK3:	clock_bits = 5; break;
1748c2ecf20Sopenharmony_ci		case QE_CLK4:	clock_bits = 6; break;
1758c2ecf20Sopenharmony_ci		case QE_CLK17:	clock_bits = 7; break;
1768c2ecf20Sopenharmony_ci		case QE_CLK18:	clock_bits = 8; break;
1778c2ecf20Sopenharmony_ci		case QE_CLK7:	clock_bits = 9; break;
1788c2ecf20Sopenharmony_ci		case QE_CLK8:	clock_bits = 10; break;
1798c2ecf20Sopenharmony_ci		case QE_CLK16:	clock_bits = 11; break;
1808c2ecf20Sopenharmony_ci		default: break;
1818c2ecf20Sopenharmony_ci		}
1828c2ecf20Sopenharmony_ci		break;
1838c2ecf20Sopenharmony_ci	case 4:
1848c2ecf20Sopenharmony_ci		switch (clock) {
1858c2ecf20Sopenharmony_ci		case QE_BRG13:	clock_bits = 1; break;
1868c2ecf20Sopenharmony_ci		case QE_BRG14:	clock_bits = 2; break;
1878c2ecf20Sopenharmony_ci		case QE_BRG15:	clock_bits = 3; break;
1888c2ecf20Sopenharmony_ci		case QE_BRG16:	clock_bits = 4; break;
1898c2ecf20Sopenharmony_ci		case QE_CLK5:	clock_bits = 5; break;
1908c2ecf20Sopenharmony_ci		case QE_CLK6:	clock_bits = 6; break;
1918c2ecf20Sopenharmony_ci		case QE_CLK21:	clock_bits = 7; break;
1928c2ecf20Sopenharmony_ci		case QE_CLK22:	clock_bits = 8; break;
1938c2ecf20Sopenharmony_ci		case QE_CLK7:	clock_bits = 9; break;
1948c2ecf20Sopenharmony_ci		case QE_CLK8:	clock_bits = 10; break;
1958c2ecf20Sopenharmony_ci		case QE_CLK16:	clock_bits = 11; break;
1968c2ecf20Sopenharmony_ci		default: break;
1978c2ecf20Sopenharmony_ci		}
1988c2ecf20Sopenharmony_ci		break;
1998c2ecf20Sopenharmony_ci	default: break;
2008c2ecf20Sopenharmony_ci	}
2018c2ecf20Sopenharmony_ci
2028c2ecf20Sopenharmony_ci	/* Check for invalid combination of clock and UCC number */
2038c2ecf20Sopenharmony_ci	if (!clock_bits)
2048c2ecf20Sopenharmony_ci		return -ENOENT;
2058c2ecf20Sopenharmony_ci
2068c2ecf20Sopenharmony_ci	if (mode == COMM_DIR_RX)
2078c2ecf20Sopenharmony_ci		shift += 4;
2088c2ecf20Sopenharmony_ci
2098c2ecf20Sopenharmony_ci	qe_clrsetbits_be32(cmxucr, QE_CMXUCR_TX_CLK_SRC_MASK << shift,
2108c2ecf20Sopenharmony_ci			   clock_bits << shift);
2118c2ecf20Sopenharmony_ci
2128c2ecf20Sopenharmony_ci	return 0;
2138c2ecf20Sopenharmony_ci}
2148c2ecf20Sopenharmony_ci
2158c2ecf20Sopenharmony_cistatic int ucc_get_tdm_common_clk(u32 tdm_num, enum qe_clock clock)
2168c2ecf20Sopenharmony_ci{
2178c2ecf20Sopenharmony_ci	int clock_bits = -EINVAL;
2188c2ecf20Sopenharmony_ci
2198c2ecf20Sopenharmony_ci	/*
2208c2ecf20Sopenharmony_ci	 * for TDM[0, 1, 2, 3], TX and RX use  common
2218c2ecf20Sopenharmony_ci	 * clock source BRG3,4 and CLK1,2
2228c2ecf20Sopenharmony_ci	 * for TDM[4, 5, 6, 7], TX and RX use  common
2238c2ecf20Sopenharmony_ci	 * clock source BRG12,13 and CLK23,24
2248c2ecf20Sopenharmony_ci	 */
2258c2ecf20Sopenharmony_ci	switch (tdm_num) {
2268c2ecf20Sopenharmony_ci	case 0:
2278c2ecf20Sopenharmony_ci	case 1:
2288c2ecf20Sopenharmony_ci	case 2:
2298c2ecf20Sopenharmony_ci	case 3:
2308c2ecf20Sopenharmony_ci		switch (clock) {
2318c2ecf20Sopenharmony_ci		case QE_BRG3:
2328c2ecf20Sopenharmony_ci			clock_bits = 1;
2338c2ecf20Sopenharmony_ci			break;
2348c2ecf20Sopenharmony_ci		case QE_BRG4:
2358c2ecf20Sopenharmony_ci			clock_bits = 2;
2368c2ecf20Sopenharmony_ci			break;
2378c2ecf20Sopenharmony_ci		case QE_CLK1:
2388c2ecf20Sopenharmony_ci			clock_bits = 4;
2398c2ecf20Sopenharmony_ci			break;
2408c2ecf20Sopenharmony_ci		case QE_CLK2:
2418c2ecf20Sopenharmony_ci			clock_bits = 5;
2428c2ecf20Sopenharmony_ci			break;
2438c2ecf20Sopenharmony_ci		default:
2448c2ecf20Sopenharmony_ci			break;
2458c2ecf20Sopenharmony_ci		}
2468c2ecf20Sopenharmony_ci		break;
2478c2ecf20Sopenharmony_ci	case 4:
2488c2ecf20Sopenharmony_ci	case 5:
2498c2ecf20Sopenharmony_ci	case 6:
2508c2ecf20Sopenharmony_ci	case 7:
2518c2ecf20Sopenharmony_ci		switch (clock) {
2528c2ecf20Sopenharmony_ci		case QE_BRG12:
2538c2ecf20Sopenharmony_ci			clock_bits = 1;
2548c2ecf20Sopenharmony_ci			break;
2558c2ecf20Sopenharmony_ci		case QE_BRG13:
2568c2ecf20Sopenharmony_ci			clock_bits = 2;
2578c2ecf20Sopenharmony_ci			break;
2588c2ecf20Sopenharmony_ci		case QE_CLK23:
2598c2ecf20Sopenharmony_ci			clock_bits = 4;
2608c2ecf20Sopenharmony_ci			break;
2618c2ecf20Sopenharmony_ci		case QE_CLK24:
2628c2ecf20Sopenharmony_ci			clock_bits = 5;
2638c2ecf20Sopenharmony_ci			break;
2648c2ecf20Sopenharmony_ci		default:
2658c2ecf20Sopenharmony_ci			break;
2668c2ecf20Sopenharmony_ci		}
2678c2ecf20Sopenharmony_ci		break;
2688c2ecf20Sopenharmony_ci	default:
2698c2ecf20Sopenharmony_ci		break;
2708c2ecf20Sopenharmony_ci	}
2718c2ecf20Sopenharmony_ci
2728c2ecf20Sopenharmony_ci	return clock_bits;
2738c2ecf20Sopenharmony_ci}
2748c2ecf20Sopenharmony_ci
2758c2ecf20Sopenharmony_cistatic int ucc_get_tdm_rx_clk(u32 tdm_num, enum qe_clock clock)
2768c2ecf20Sopenharmony_ci{
2778c2ecf20Sopenharmony_ci	int clock_bits = -EINVAL;
2788c2ecf20Sopenharmony_ci
2798c2ecf20Sopenharmony_ci	switch (tdm_num) {
2808c2ecf20Sopenharmony_ci	case 0:
2818c2ecf20Sopenharmony_ci		switch (clock) {
2828c2ecf20Sopenharmony_ci		case QE_CLK3:
2838c2ecf20Sopenharmony_ci			clock_bits = 6;
2848c2ecf20Sopenharmony_ci			break;
2858c2ecf20Sopenharmony_ci		case QE_CLK8:
2868c2ecf20Sopenharmony_ci			clock_bits = 7;
2878c2ecf20Sopenharmony_ci			break;
2888c2ecf20Sopenharmony_ci		default:
2898c2ecf20Sopenharmony_ci			break;
2908c2ecf20Sopenharmony_ci		}
2918c2ecf20Sopenharmony_ci		break;
2928c2ecf20Sopenharmony_ci	case 1:
2938c2ecf20Sopenharmony_ci		switch (clock) {
2948c2ecf20Sopenharmony_ci		case QE_CLK5:
2958c2ecf20Sopenharmony_ci			clock_bits = 6;
2968c2ecf20Sopenharmony_ci			break;
2978c2ecf20Sopenharmony_ci		case QE_CLK10:
2988c2ecf20Sopenharmony_ci			clock_bits = 7;
2998c2ecf20Sopenharmony_ci			break;
3008c2ecf20Sopenharmony_ci		default:
3018c2ecf20Sopenharmony_ci			break;
3028c2ecf20Sopenharmony_ci		}
3038c2ecf20Sopenharmony_ci		break;
3048c2ecf20Sopenharmony_ci	case 2:
3058c2ecf20Sopenharmony_ci		switch (clock) {
3068c2ecf20Sopenharmony_ci		case QE_CLK7:
3078c2ecf20Sopenharmony_ci			clock_bits = 6;
3088c2ecf20Sopenharmony_ci			break;
3098c2ecf20Sopenharmony_ci		case QE_CLK12:
3108c2ecf20Sopenharmony_ci			clock_bits = 7;
3118c2ecf20Sopenharmony_ci			break;
3128c2ecf20Sopenharmony_ci		default:
3138c2ecf20Sopenharmony_ci			break;
3148c2ecf20Sopenharmony_ci		}
3158c2ecf20Sopenharmony_ci		break;
3168c2ecf20Sopenharmony_ci	case 3:
3178c2ecf20Sopenharmony_ci		switch (clock) {
3188c2ecf20Sopenharmony_ci		case QE_CLK9:
3198c2ecf20Sopenharmony_ci			clock_bits = 6;
3208c2ecf20Sopenharmony_ci			break;
3218c2ecf20Sopenharmony_ci		case QE_CLK14:
3228c2ecf20Sopenharmony_ci			clock_bits = 7;
3238c2ecf20Sopenharmony_ci			break;
3248c2ecf20Sopenharmony_ci		default:
3258c2ecf20Sopenharmony_ci			break;
3268c2ecf20Sopenharmony_ci		}
3278c2ecf20Sopenharmony_ci		break;
3288c2ecf20Sopenharmony_ci	case 4:
3298c2ecf20Sopenharmony_ci		switch (clock) {
3308c2ecf20Sopenharmony_ci		case QE_CLK11:
3318c2ecf20Sopenharmony_ci			clock_bits = 6;
3328c2ecf20Sopenharmony_ci			break;
3338c2ecf20Sopenharmony_ci		case QE_CLK16:
3348c2ecf20Sopenharmony_ci			clock_bits = 7;
3358c2ecf20Sopenharmony_ci			break;
3368c2ecf20Sopenharmony_ci		default:
3378c2ecf20Sopenharmony_ci			break;
3388c2ecf20Sopenharmony_ci		}
3398c2ecf20Sopenharmony_ci		break;
3408c2ecf20Sopenharmony_ci	case 5:
3418c2ecf20Sopenharmony_ci		switch (clock) {
3428c2ecf20Sopenharmony_ci		case QE_CLK13:
3438c2ecf20Sopenharmony_ci			clock_bits = 6;
3448c2ecf20Sopenharmony_ci			break;
3458c2ecf20Sopenharmony_ci		case QE_CLK18:
3468c2ecf20Sopenharmony_ci			clock_bits = 7;
3478c2ecf20Sopenharmony_ci			break;
3488c2ecf20Sopenharmony_ci		default:
3498c2ecf20Sopenharmony_ci			break;
3508c2ecf20Sopenharmony_ci		}
3518c2ecf20Sopenharmony_ci		break;
3528c2ecf20Sopenharmony_ci	case 6:
3538c2ecf20Sopenharmony_ci		switch (clock) {
3548c2ecf20Sopenharmony_ci		case QE_CLK15:
3558c2ecf20Sopenharmony_ci			clock_bits = 6;
3568c2ecf20Sopenharmony_ci			break;
3578c2ecf20Sopenharmony_ci		case QE_CLK20:
3588c2ecf20Sopenharmony_ci			clock_bits = 7;
3598c2ecf20Sopenharmony_ci			break;
3608c2ecf20Sopenharmony_ci		default:
3618c2ecf20Sopenharmony_ci			break;
3628c2ecf20Sopenharmony_ci		}
3638c2ecf20Sopenharmony_ci		break;
3648c2ecf20Sopenharmony_ci	case 7:
3658c2ecf20Sopenharmony_ci		switch (clock) {
3668c2ecf20Sopenharmony_ci		case QE_CLK17:
3678c2ecf20Sopenharmony_ci			clock_bits = 6;
3688c2ecf20Sopenharmony_ci			break;
3698c2ecf20Sopenharmony_ci		case QE_CLK22:
3708c2ecf20Sopenharmony_ci			clock_bits = 7;
3718c2ecf20Sopenharmony_ci			break;
3728c2ecf20Sopenharmony_ci		default:
3738c2ecf20Sopenharmony_ci			break;
3748c2ecf20Sopenharmony_ci		}
3758c2ecf20Sopenharmony_ci		break;
3768c2ecf20Sopenharmony_ci	}
3778c2ecf20Sopenharmony_ci
3788c2ecf20Sopenharmony_ci	return clock_bits;
3798c2ecf20Sopenharmony_ci}
3808c2ecf20Sopenharmony_ci
3818c2ecf20Sopenharmony_cistatic int ucc_get_tdm_tx_clk(u32 tdm_num, enum qe_clock clock)
3828c2ecf20Sopenharmony_ci{
3838c2ecf20Sopenharmony_ci	int clock_bits = -EINVAL;
3848c2ecf20Sopenharmony_ci
3858c2ecf20Sopenharmony_ci	switch (tdm_num) {
3868c2ecf20Sopenharmony_ci	case 0:
3878c2ecf20Sopenharmony_ci		switch (clock) {
3888c2ecf20Sopenharmony_ci		case QE_CLK4:
3898c2ecf20Sopenharmony_ci			clock_bits = 6;
3908c2ecf20Sopenharmony_ci			break;
3918c2ecf20Sopenharmony_ci		case QE_CLK9:
3928c2ecf20Sopenharmony_ci			clock_bits = 7;
3938c2ecf20Sopenharmony_ci			break;
3948c2ecf20Sopenharmony_ci		default:
3958c2ecf20Sopenharmony_ci			break;
3968c2ecf20Sopenharmony_ci		}
3978c2ecf20Sopenharmony_ci		break;
3988c2ecf20Sopenharmony_ci	case 1:
3998c2ecf20Sopenharmony_ci		switch (clock) {
4008c2ecf20Sopenharmony_ci		case QE_CLK6:
4018c2ecf20Sopenharmony_ci			clock_bits = 6;
4028c2ecf20Sopenharmony_ci			break;
4038c2ecf20Sopenharmony_ci		case QE_CLK11:
4048c2ecf20Sopenharmony_ci			clock_bits = 7;
4058c2ecf20Sopenharmony_ci			break;
4068c2ecf20Sopenharmony_ci		default:
4078c2ecf20Sopenharmony_ci			break;
4088c2ecf20Sopenharmony_ci		}
4098c2ecf20Sopenharmony_ci		break;
4108c2ecf20Sopenharmony_ci	case 2:
4118c2ecf20Sopenharmony_ci		switch (clock) {
4128c2ecf20Sopenharmony_ci		case QE_CLK8:
4138c2ecf20Sopenharmony_ci			clock_bits = 6;
4148c2ecf20Sopenharmony_ci			break;
4158c2ecf20Sopenharmony_ci		case QE_CLK13:
4168c2ecf20Sopenharmony_ci			clock_bits = 7;
4178c2ecf20Sopenharmony_ci			break;
4188c2ecf20Sopenharmony_ci		default:
4198c2ecf20Sopenharmony_ci			break;
4208c2ecf20Sopenharmony_ci		}
4218c2ecf20Sopenharmony_ci		break;
4228c2ecf20Sopenharmony_ci	case 3:
4238c2ecf20Sopenharmony_ci		switch (clock) {
4248c2ecf20Sopenharmony_ci		case QE_CLK10:
4258c2ecf20Sopenharmony_ci			clock_bits = 6;
4268c2ecf20Sopenharmony_ci			break;
4278c2ecf20Sopenharmony_ci		case QE_CLK15:
4288c2ecf20Sopenharmony_ci			clock_bits = 7;
4298c2ecf20Sopenharmony_ci			break;
4308c2ecf20Sopenharmony_ci		default:
4318c2ecf20Sopenharmony_ci			break;
4328c2ecf20Sopenharmony_ci		}
4338c2ecf20Sopenharmony_ci		break;
4348c2ecf20Sopenharmony_ci	case 4:
4358c2ecf20Sopenharmony_ci		switch (clock) {
4368c2ecf20Sopenharmony_ci		case QE_CLK12:
4378c2ecf20Sopenharmony_ci			clock_bits = 6;
4388c2ecf20Sopenharmony_ci			break;
4398c2ecf20Sopenharmony_ci		case QE_CLK17:
4408c2ecf20Sopenharmony_ci			clock_bits = 7;
4418c2ecf20Sopenharmony_ci			break;
4428c2ecf20Sopenharmony_ci		default:
4438c2ecf20Sopenharmony_ci			break;
4448c2ecf20Sopenharmony_ci		}
4458c2ecf20Sopenharmony_ci		break;
4468c2ecf20Sopenharmony_ci	case 5:
4478c2ecf20Sopenharmony_ci		switch (clock) {
4488c2ecf20Sopenharmony_ci		case QE_CLK14:
4498c2ecf20Sopenharmony_ci			clock_bits = 6;
4508c2ecf20Sopenharmony_ci			break;
4518c2ecf20Sopenharmony_ci		case QE_CLK19:
4528c2ecf20Sopenharmony_ci			clock_bits = 7;
4538c2ecf20Sopenharmony_ci			break;
4548c2ecf20Sopenharmony_ci		default:
4558c2ecf20Sopenharmony_ci			break;
4568c2ecf20Sopenharmony_ci		}
4578c2ecf20Sopenharmony_ci		break;
4588c2ecf20Sopenharmony_ci	case 6:
4598c2ecf20Sopenharmony_ci		switch (clock) {
4608c2ecf20Sopenharmony_ci		case QE_CLK16:
4618c2ecf20Sopenharmony_ci			clock_bits = 6;
4628c2ecf20Sopenharmony_ci			break;
4638c2ecf20Sopenharmony_ci		case QE_CLK21:
4648c2ecf20Sopenharmony_ci			clock_bits = 7;
4658c2ecf20Sopenharmony_ci			break;
4668c2ecf20Sopenharmony_ci		default:
4678c2ecf20Sopenharmony_ci			break;
4688c2ecf20Sopenharmony_ci		}
4698c2ecf20Sopenharmony_ci		break;
4708c2ecf20Sopenharmony_ci	case 7:
4718c2ecf20Sopenharmony_ci		switch (clock) {
4728c2ecf20Sopenharmony_ci		case QE_CLK18:
4738c2ecf20Sopenharmony_ci			clock_bits = 6;
4748c2ecf20Sopenharmony_ci			break;
4758c2ecf20Sopenharmony_ci		case QE_CLK3:
4768c2ecf20Sopenharmony_ci			clock_bits = 7;
4778c2ecf20Sopenharmony_ci			break;
4788c2ecf20Sopenharmony_ci		default:
4798c2ecf20Sopenharmony_ci			break;
4808c2ecf20Sopenharmony_ci		}
4818c2ecf20Sopenharmony_ci		break;
4828c2ecf20Sopenharmony_ci	}
4838c2ecf20Sopenharmony_ci
4848c2ecf20Sopenharmony_ci	return clock_bits;
4858c2ecf20Sopenharmony_ci}
4868c2ecf20Sopenharmony_ci
4878c2ecf20Sopenharmony_ci/* tdm_num: TDM A-H port num is 0-7 */
4888c2ecf20Sopenharmony_cistatic int ucc_get_tdm_rxtx_clk(enum comm_dir mode, u32 tdm_num,
4898c2ecf20Sopenharmony_ci				enum qe_clock clock)
4908c2ecf20Sopenharmony_ci{
4918c2ecf20Sopenharmony_ci	int clock_bits;
4928c2ecf20Sopenharmony_ci
4938c2ecf20Sopenharmony_ci	clock_bits = ucc_get_tdm_common_clk(tdm_num, clock);
4948c2ecf20Sopenharmony_ci	if (clock_bits > 0)
4958c2ecf20Sopenharmony_ci		return clock_bits;
4968c2ecf20Sopenharmony_ci	if (mode == COMM_DIR_RX)
4978c2ecf20Sopenharmony_ci		clock_bits = ucc_get_tdm_rx_clk(tdm_num, clock);
4988c2ecf20Sopenharmony_ci	if (mode == COMM_DIR_TX)
4998c2ecf20Sopenharmony_ci		clock_bits = ucc_get_tdm_tx_clk(tdm_num, clock);
5008c2ecf20Sopenharmony_ci	return clock_bits;
5018c2ecf20Sopenharmony_ci}
5028c2ecf20Sopenharmony_ci
5038c2ecf20Sopenharmony_cistatic u32 ucc_get_tdm_clk_shift(enum comm_dir mode, u32 tdm_num)
5048c2ecf20Sopenharmony_ci{
5058c2ecf20Sopenharmony_ci	u32 shift;
5068c2ecf20Sopenharmony_ci
5078c2ecf20Sopenharmony_ci	shift = (mode == COMM_DIR_RX) ? RX_CLK_SHIFT_BASE : TX_CLK_SHIFT_BASE;
5088c2ecf20Sopenharmony_ci	if (tdm_num < 4)
5098c2ecf20Sopenharmony_ci		shift -= tdm_num * 4;
5108c2ecf20Sopenharmony_ci	else
5118c2ecf20Sopenharmony_ci		shift -= (tdm_num - 4) * 4;
5128c2ecf20Sopenharmony_ci
5138c2ecf20Sopenharmony_ci	return shift;
5148c2ecf20Sopenharmony_ci}
5158c2ecf20Sopenharmony_ci
5168c2ecf20Sopenharmony_ciint ucc_set_tdm_rxtx_clk(u32 tdm_num, enum qe_clock clock,
5178c2ecf20Sopenharmony_ci			 enum comm_dir mode)
5188c2ecf20Sopenharmony_ci{
5198c2ecf20Sopenharmony_ci	int clock_bits;
5208c2ecf20Sopenharmony_ci	u32 shift;
5218c2ecf20Sopenharmony_ci	struct qe_mux __iomem *qe_mux_reg;
5228c2ecf20Sopenharmony_ci	__be32 __iomem *cmxs1cr;
5238c2ecf20Sopenharmony_ci
5248c2ecf20Sopenharmony_ci	qe_mux_reg = &qe_immr->qmx;
5258c2ecf20Sopenharmony_ci
5268c2ecf20Sopenharmony_ci	if (tdm_num > 7)
5278c2ecf20Sopenharmony_ci		return -EINVAL;
5288c2ecf20Sopenharmony_ci
5298c2ecf20Sopenharmony_ci	/* The communications direction must be RX or TX */
5308c2ecf20Sopenharmony_ci	if (mode != COMM_DIR_RX && mode != COMM_DIR_TX)
5318c2ecf20Sopenharmony_ci		return -EINVAL;
5328c2ecf20Sopenharmony_ci
5338c2ecf20Sopenharmony_ci	clock_bits = ucc_get_tdm_rxtx_clk(mode, tdm_num, clock);
5348c2ecf20Sopenharmony_ci	if (clock_bits < 0)
5358c2ecf20Sopenharmony_ci		return -EINVAL;
5368c2ecf20Sopenharmony_ci
5378c2ecf20Sopenharmony_ci	shift = ucc_get_tdm_clk_shift(mode, tdm_num);
5388c2ecf20Sopenharmony_ci
5398c2ecf20Sopenharmony_ci	cmxs1cr = (tdm_num < 4) ? &qe_mux_reg->cmxsi1cr_l :
5408c2ecf20Sopenharmony_ci				  &qe_mux_reg->cmxsi1cr_h;
5418c2ecf20Sopenharmony_ci
5428c2ecf20Sopenharmony_ci	qe_clrsetbits_be32(cmxs1cr, QE_CMXUCR_TX_CLK_SRC_MASK << shift,
5438c2ecf20Sopenharmony_ci			   clock_bits << shift);
5448c2ecf20Sopenharmony_ci
5458c2ecf20Sopenharmony_ci	return 0;
5468c2ecf20Sopenharmony_ci}
5478c2ecf20Sopenharmony_ci
5488c2ecf20Sopenharmony_cistatic int ucc_get_tdm_sync_source(u32 tdm_num, enum qe_clock clock,
5498c2ecf20Sopenharmony_ci				   enum comm_dir mode)
5508c2ecf20Sopenharmony_ci{
5518c2ecf20Sopenharmony_ci	int source = -EINVAL;
5528c2ecf20Sopenharmony_ci
5538c2ecf20Sopenharmony_ci	if (mode == COMM_DIR_RX && clock == QE_RSYNC_PIN) {
5548c2ecf20Sopenharmony_ci		source = 0;
5558c2ecf20Sopenharmony_ci		return source;
5568c2ecf20Sopenharmony_ci	}
5578c2ecf20Sopenharmony_ci	if (mode == COMM_DIR_TX && clock == QE_TSYNC_PIN) {
5588c2ecf20Sopenharmony_ci		source = 0;
5598c2ecf20Sopenharmony_ci		return source;
5608c2ecf20Sopenharmony_ci	}
5618c2ecf20Sopenharmony_ci
5628c2ecf20Sopenharmony_ci	switch (tdm_num) {
5638c2ecf20Sopenharmony_ci	case 0:
5648c2ecf20Sopenharmony_ci	case 1:
5658c2ecf20Sopenharmony_ci		switch (clock) {
5668c2ecf20Sopenharmony_ci		case QE_BRG9:
5678c2ecf20Sopenharmony_ci			source = 1;
5688c2ecf20Sopenharmony_ci			break;
5698c2ecf20Sopenharmony_ci		case QE_BRG10:
5708c2ecf20Sopenharmony_ci			source = 2;
5718c2ecf20Sopenharmony_ci			break;
5728c2ecf20Sopenharmony_ci		default:
5738c2ecf20Sopenharmony_ci			break;
5748c2ecf20Sopenharmony_ci		}
5758c2ecf20Sopenharmony_ci		break;
5768c2ecf20Sopenharmony_ci	case 2:
5778c2ecf20Sopenharmony_ci	case 3:
5788c2ecf20Sopenharmony_ci		switch (clock) {
5798c2ecf20Sopenharmony_ci		case QE_BRG9:
5808c2ecf20Sopenharmony_ci			source = 1;
5818c2ecf20Sopenharmony_ci			break;
5828c2ecf20Sopenharmony_ci		case QE_BRG11:
5838c2ecf20Sopenharmony_ci			source = 2;
5848c2ecf20Sopenharmony_ci			break;
5858c2ecf20Sopenharmony_ci		default:
5868c2ecf20Sopenharmony_ci			break;
5878c2ecf20Sopenharmony_ci		}
5888c2ecf20Sopenharmony_ci		break;
5898c2ecf20Sopenharmony_ci	case 4:
5908c2ecf20Sopenharmony_ci	case 5:
5918c2ecf20Sopenharmony_ci		switch (clock) {
5928c2ecf20Sopenharmony_ci		case QE_BRG13:
5938c2ecf20Sopenharmony_ci			source = 1;
5948c2ecf20Sopenharmony_ci			break;
5958c2ecf20Sopenharmony_ci		case QE_BRG14:
5968c2ecf20Sopenharmony_ci			source = 2;
5978c2ecf20Sopenharmony_ci			break;
5988c2ecf20Sopenharmony_ci		default:
5998c2ecf20Sopenharmony_ci			break;
6008c2ecf20Sopenharmony_ci		}
6018c2ecf20Sopenharmony_ci		break;
6028c2ecf20Sopenharmony_ci	case 6:
6038c2ecf20Sopenharmony_ci	case 7:
6048c2ecf20Sopenharmony_ci		switch (clock) {
6058c2ecf20Sopenharmony_ci		case QE_BRG13:
6068c2ecf20Sopenharmony_ci			source = 1;
6078c2ecf20Sopenharmony_ci			break;
6088c2ecf20Sopenharmony_ci		case QE_BRG15:
6098c2ecf20Sopenharmony_ci			source = 2;
6108c2ecf20Sopenharmony_ci			break;
6118c2ecf20Sopenharmony_ci		default:
6128c2ecf20Sopenharmony_ci			break;
6138c2ecf20Sopenharmony_ci		}
6148c2ecf20Sopenharmony_ci		break;
6158c2ecf20Sopenharmony_ci	}
6168c2ecf20Sopenharmony_ci
6178c2ecf20Sopenharmony_ci	return source;
6188c2ecf20Sopenharmony_ci}
6198c2ecf20Sopenharmony_ci
6208c2ecf20Sopenharmony_cistatic u32 ucc_get_tdm_sync_shift(enum comm_dir mode, u32 tdm_num)
6218c2ecf20Sopenharmony_ci{
6228c2ecf20Sopenharmony_ci	u32 shift;
6238c2ecf20Sopenharmony_ci
6248c2ecf20Sopenharmony_ci	shift = (mode == COMM_DIR_RX) ? RX_SYNC_SHIFT_BASE : TX_SYNC_SHIFT_BASE;
6258c2ecf20Sopenharmony_ci	shift -= tdm_num * 2;
6268c2ecf20Sopenharmony_ci
6278c2ecf20Sopenharmony_ci	return shift;
6288c2ecf20Sopenharmony_ci}
6298c2ecf20Sopenharmony_ci
6308c2ecf20Sopenharmony_ciint ucc_set_tdm_rxtx_sync(u32 tdm_num, enum qe_clock clock,
6318c2ecf20Sopenharmony_ci			  enum comm_dir mode)
6328c2ecf20Sopenharmony_ci{
6338c2ecf20Sopenharmony_ci	int source;
6348c2ecf20Sopenharmony_ci	u32 shift;
6358c2ecf20Sopenharmony_ci	struct qe_mux __iomem *qe_mux_reg;
6368c2ecf20Sopenharmony_ci
6378c2ecf20Sopenharmony_ci	qe_mux_reg = &qe_immr->qmx;
6388c2ecf20Sopenharmony_ci
6398c2ecf20Sopenharmony_ci	if (tdm_num >= UCC_TDM_NUM)
6408c2ecf20Sopenharmony_ci		return -EINVAL;
6418c2ecf20Sopenharmony_ci
6428c2ecf20Sopenharmony_ci	/* The communications direction must be RX or TX */
6438c2ecf20Sopenharmony_ci	if (mode != COMM_DIR_RX && mode != COMM_DIR_TX)
6448c2ecf20Sopenharmony_ci		return -EINVAL;
6458c2ecf20Sopenharmony_ci
6468c2ecf20Sopenharmony_ci	source = ucc_get_tdm_sync_source(tdm_num, clock, mode);
6478c2ecf20Sopenharmony_ci	if (source < 0)
6488c2ecf20Sopenharmony_ci		return -EINVAL;
6498c2ecf20Sopenharmony_ci
6508c2ecf20Sopenharmony_ci	shift = ucc_get_tdm_sync_shift(mode, tdm_num);
6518c2ecf20Sopenharmony_ci
6528c2ecf20Sopenharmony_ci	qe_clrsetbits_be32(&qe_mux_reg->cmxsi1syr,
6538c2ecf20Sopenharmony_ci			   QE_CMXUCR_TX_CLK_SRC_MASK << shift,
6548c2ecf20Sopenharmony_ci			   source << shift);
6558c2ecf20Sopenharmony_ci
6568c2ecf20Sopenharmony_ci	return 0;
6578c2ecf20Sopenharmony_ci}
658