cachepc-linux

Fork of AMDESE/linux with modifications for CachePC side-channel attack
git clone https://git.sinitax.com/sinitax/cachepc-linux
Log | Files | Refs | README | LICENSE | sfeed.txt

ucc.c (12275B)


      1// SPDX-License-Identifier: GPL-2.0-or-later
      2/*
      3 * arch/powerpc/sysdev/qe_lib/ucc.c
      4 *
      5 * QE UCC API Set - UCC specific routines implementations.
      6 *
      7 * Copyright (C) 2006 Freescale Semiconductor, Inc. All rights reserved.
      8 *
      9 * Authors: 	Shlomi Gridish <gridish@freescale.com>
     10 * 		Li Yang <leoli@freescale.com>
     11 */
     12#include <linux/kernel.h>
     13#include <linux/errno.h>
     14#include <linux/stddef.h>
     15#include <linux/spinlock.h>
     16#include <linux/export.h>
     17
     18#include <asm/io.h>
     19#include <soc/fsl/qe/immap_qe.h>
     20#include <soc/fsl/qe/qe.h>
     21#include <soc/fsl/qe/ucc.h>
     22
     23#define UCC_TDM_NUM 8
     24#define RX_SYNC_SHIFT_BASE 30
     25#define TX_SYNC_SHIFT_BASE 14
     26#define RX_CLK_SHIFT_BASE 28
     27#define TX_CLK_SHIFT_BASE 12
     28
     29int ucc_set_qe_mux_mii_mng(unsigned int ucc_num)
     30{
     31	unsigned long flags;
     32
     33	if (ucc_num > UCC_MAX_NUM - 1)
     34		return -EINVAL;
     35
     36	spin_lock_irqsave(&cmxgcr_lock, flags);
     37	qe_clrsetbits_be32(&qe_immr->qmx.cmxgcr, QE_CMXGCR_MII_ENET_MNG,
     38			   ucc_num << QE_CMXGCR_MII_ENET_MNG_SHIFT);
     39	spin_unlock_irqrestore(&cmxgcr_lock, flags);
     40
     41	return 0;
     42}
     43EXPORT_SYMBOL(ucc_set_qe_mux_mii_mng);
     44
     45/* Configure the UCC to either Slow or Fast.
     46 *
     47 * A given UCC can be figured to support either "slow" devices (e.g. UART)
     48 * or "fast" devices (e.g. Ethernet).
     49 *
     50 * 'ucc_num' is the UCC number, from 0 - 7.
     51 *
     52 * This function also sets the UCC_GUEMR_SET_RESERVED3 bit because that bit
     53 * must always be set to 1.
     54 */
     55int ucc_set_type(unsigned int ucc_num, enum ucc_speed_type speed)
     56{
     57	u8 __iomem *guemr;
     58
     59	/* The GUEMR register is at the same location for both slow and fast
     60	   devices, so we just use uccX.slow.guemr. */
     61	switch (ucc_num) {
     62	case 0: guemr = &qe_immr->ucc1.slow.guemr;
     63		break;
     64	case 1: guemr = &qe_immr->ucc2.slow.guemr;
     65		break;
     66	case 2: guemr = &qe_immr->ucc3.slow.guemr;
     67		break;
     68	case 3: guemr = &qe_immr->ucc4.slow.guemr;
     69		break;
     70	case 4: guemr = &qe_immr->ucc5.slow.guemr;
     71		break;
     72	case 5: guemr = &qe_immr->ucc6.slow.guemr;
     73		break;
     74	case 6: guemr = &qe_immr->ucc7.slow.guemr;
     75		break;
     76	case 7: guemr = &qe_immr->ucc8.slow.guemr;
     77		break;
     78	default:
     79		return -EINVAL;
     80	}
     81
     82	qe_clrsetbits_8(guemr, UCC_GUEMR_MODE_MASK,
     83			UCC_GUEMR_SET_RESERVED3 | speed);
     84
     85	return 0;
     86}
     87
     88static void get_cmxucr_reg(unsigned int ucc_num, __be32 __iomem **cmxucr,
     89	unsigned int *reg_num, unsigned int *shift)
     90{
     91	unsigned int cmx = ((ucc_num & 1) << 1) + (ucc_num > 3);
     92
     93	*reg_num = cmx + 1;
     94	*cmxucr = &qe_immr->qmx.cmxucr[cmx];
     95	*shift = 16 - 8 * (ucc_num & 2);
     96}
     97
     98int ucc_mux_set_grant_tsa_bkpt(unsigned int ucc_num, int set, u32 mask)
     99{
    100	__be32 __iomem *cmxucr;
    101	unsigned int reg_num;
    102	unsigned int shift;
    103
    104	/* check if the UCC number is in range. */
    105	if (ucc_num > UCC_MAX_NUM - 1)
    106		return -EINVAL;
    107
    108	get_cmxucr_reg(ucc_num, &cmxucr, &reg_num, &shift);
    109
    110	if (set)
    111		qe_setbits_be32(cmxucr, mask << shift);
    112	else
    113		qe_clrbits_be32(cmxucr, mask << shift);
    114
    115	return 0;
    116}
    117
    118int ucc_set_qe_mux_rxtx(unsigned int ucc_num, enum qe_clock clock,
    119	enum comm_dir mode)
    120{
    121	__be32 __iomem *cmxucr;
    122	unsigned int reg_num;
    123	unsigned int shift;
    124	u32 clock_bits = 0;
    125
    126	/* check if the UCC number is in range. */
    127	if (ucc_num > UCC_MAX_NUM - 1)
    128		return -EINVAL;
    129
    130	/* The communications direction must be RX or TX */
    131	if (!((mode == COMM_DIR_RX) || (mode == COMM_DIR_TX)))
    132		return -EINVAL;
    133
    134	get_cmxucr_reg(ucc_num, &cmxucr, &reg_num, &shift);
    135
    136	switch (reg_num) {
    137	case 1:
    138		switch (clock) {
    139		case QE_BRG1:	clock_bits = 1; break;
    140		case QE_BRG2:	clock_bits = 2; break;
    141		case QE_BRG7:	clock_bits = 3; break;
    142		case QE_BRG8:	clock_bits = 4; break;
    143		case QE_CLK9:	clock_bits = 5; break;
    144		case QE_CLK10:	clock_bits = 6; break;
    145		case QE_CLK11:	clock_bits = 7; break;
    146		case QE_CLK12:	clock_bits = 8; break;
    147		case QE_CLK15:	clock_bits = 9; break;
    148		case QE_CLK16:	clock_bits = 10; break;
    149		default: break;
    150		}
    151		break;
    152	case 2:
    153		switch (clock) {
    154		case QE_BRG5:	clock_bits = 1; break;
    155		case QE_BRG6:	clock_bits = 2; break;
    156		case QE_BRG7:	clock_bits = 3; break;
    157		case QE_BRG8:	clock_bits = 4; break;
    158		case QE_CLK13:	clock_bits = 5; break;
    159		case QE_CLK14:	clock_bits = 6; break;
    160		case QE_CLK19:	clock_bits = 7; break;
    161		case QE_CLK20:	clock_bits = 8; break;
    162		case QE_CLK15:	clock_bits = 9; break;
    163		case QE_CLK16:	clock_bits = 10; break;
    164		default: break;
    165		}
    166		break;
    167	case 3:
    168		switch (clock) {
    169		case QE_BRG9:	clock_bits = 1; break;
    170		case QE_BRG10:	clock_bits = 2; break;
    171		case QE_BRG15:	clock_bits = 3; break;
    172		case QE_BRG16:	clock_bits = 4; break;
    173		case QE_CLK3:	clock_bits = 5; break;
    174		case QE_CLK4:	clock_bits = 6; break;
    175		case QE_CLK17:	clock_bits = 7; break;
    176		case QE_CLK18:	clock_bits = 8; break;
    177		case QE_CLK7:	clock_bits = 9; break;
    178		case QE_CLK8:	clock_bits = 10; break;
    179		case QE_CLK16:	clock_bits = 11; break;
    180		default: break;
    181		}
    182		break;
    183	case 4:
    184		switch (clock) {
    185		case QE_BRG13:	clock_bits = 1; break;
    186		case QE_BRG14:	clock_bits = 2; break;
    187		case QE_BRG15:	clock_bits = 3; break;
    188		case QE_BRG16:	clock_bits = 4; break;
    189		case QE_CLK5:	clock_bits = 5; break;
    190		case QE_CLK6:	clock_bits = 6; break;
    191		case QE_CLK21:	clock_bits = 7; break;
    192		case QE_CLK22:	clock_bits = 8; break;
    193		case QE_CLK7:	clock_bits = 9; break;
    194		case QE_CLK8:	clock_bits = 10; break;
    195		case QE_CLK16:	clock_bits = 11; break;
    196		default: break;
    197		}
    198		break;
    199	default: break;
    200	}
    201
    202	/* Check for invalid combination of clock and UCC number */
    203	if (!clock_bits)
    204		return -ENOENT;
    205
    206	if (mode == COMM_DIR_RX)
    207		shift += 4;
    208
    209	qe_clrsetbits_be32(cmxucr, QE_CMXUCR_TX_CLK_SRC_MASK << shift,
    210			   clock_bits << shift);
    211
    212	return 0;
    213}
    214
    215static int ucc_get_tdm_common_clk(u32 tdm_num, enum qe_clock clock)
    216{
    217	int clock_bits = -EINVAL;
    218
    219	/*
    220	 * for TDM[0, 1, 2, 3], TX and RX use  common
    221	 * clock source BRG3,4 and CLK1,2
    222	 * for TDM[4, 5, 6, 7], TX and RX use  common
    223	 * clock source BRG12,13 and CLK23,24
    224	 */
    225	switch (tdm_num) {
    226	case 0:
    227	case 1:
    228	case 2:
    229	case 3:
    230		switch (clock) {
    231		case QE_BRG3:
    232			clock_bits = 1;
    233			break;
    234		case QE_BRG4:
    235			clock_bits = 2;
    236			break;
    237		case QE_CLK1:
    238			clock_bits = 4;
    239			break;
    240		case QE_CLK2:
    241			clock_bits = 5;
    242			break;
    243		default:
    244			break;
    245		}
    246		break;
    247	case 4:
    248	case 5:
    249	case 6:
    250	case 7:
    251		switch (clock) {
    252		case QE_BRG12:
    253			clock_bits = 1;
    254			break;
    255		case QE_BRG13:
    256			clock_bits = 2;
    257			break;
    258		case QE_CLK23:
    259			clock_bits = 4;
    260			break;
    261		case QE_CLK24:
    262			clock_bits = 5;
    263			break;
    264		default:
    265			break;
    266		}
    267		break;
    268	default:
    269		break;
    270	}
    271
    272	return clock_bits;
    273}
    274
    275static int ucc_get_tdm_rx_clk(u32 tdm_num, enum qe_clock clock)
    276{
    277	int clock_bits = -EINVAL;
    278
    279	switch (tdm_num) {
    280	case 0:
    281		switch (clock) {
    282		case QE_CLK3:
    283			clock_bits = 6;
    284			break;
    285		case QE_CLK8:
    286			clock_bits = 7;
    287			break;
    288		default:
    289			break;
    290		}
    291		break;
    292	case 1:
    293		switch (clock) {
    294		case QE_CLK5:
    295			clock_bits = 6;
    296			break;
    297		case QE_CLK10:
    298			clock_bits = 7;
    299			break;
    300		default:
    301			break;
    302		}
    303		break;
    304	case 2:
    305		switch (clock) {
    306		case QE_CLK7:
    307			clock_bits = 6;
    308			break;
    309		case QE_CLK12:
    310			clock_bits = 7;
    311			break;
    312		default:
    313			break;
    314		}
    315		break;
    316	case 3:
    317		switch (clock) {
    318		case QE_CLK9:
    319			clock_bits = 6;
    320			break;
    321		case QE_CLK14:
    322			clock_bits = 7;
    323			break;
    324		default:
    325			break;
    326		}
    327		break;
    328	case 4:
    329		switch (clock) {
    330		case QE_CLK11:
    331			clock_bits = 6;
    332			break;
    333		case QE_CLK16:
    334			clock_bits = 7;
    335			break;
    336		default:
    337			break;
    338		}
    339		break;
    340	case 5:
    341		switch (clock) {
    342		case QE_CLK13:
    343			clock_bits = 6;
    344			break;
    345		case QE_CLK18:
    346			clock_bits = 7;
    347			break;
    348		default:
    349			break;
    350		}
    351		break;
    352	case 6:
    353		switch (clock) {
    354		case QE_CLK15:
    355			clock_bits = 6;
    356			break;
    357		case QE_CLK20:
    358			clock_bits = 7;
    359			break;
    360		default:
    361			break;
    362		}
    363		break;
    364	case 7:
    365		switch (clock) {
    366		case QE_CLK17:
    367			clock_bits = 6;
    368			break;
    369		case QE_CLK22:
    370			clock_bits = 7;
    371			break;
    372		default:
    373			break;
    374		}
    375		break;
    376	}
    377
    378	return clock_bits;
    379}
    380
    381static int ucc_get_tdm_tx_clk(u32 tdm_num, enum qe_clock clock)
    382{
    383	int clock_bits = -EINVAL;
    384
    385	switch (tdm_num) {
    386	case 0:
    387		switch (clock) {
    388		case QE_CLK4:
    389			clock_bits = 6;
    390			break;
    391		case QE_CLK9:
    392			clock_bits = 7;
    393			break;
    394		default:
    395			break;
    396		}
    397		break;
    398	case 1:
    399		switch (clock) {
    400		case QE_CLK6:
    401			clock_bits = 6;
    402			break;
    403		case QE_CLK11:
    404			clock_bits = 7;
    405			break;
    406		default:
    407			break;
    408		}
    409		break;
    410	case 2:
    411		switch (clock) {
    412		case QE_CLK8:
    413			clock_bits = 6;
    414			break;
    415		case QE_CLK13:
    416			clock_bits = 7;
    417			break;
    418		default:
    419			break;
    420		}
    421		break;
    422	case 3:
    423		switch (clock) {
    424		case QE_CLK10:
    425			clock_bits = 6;
    426			break;
    427		case QE_CLK15:
    428			clock_bits = 7;
    429			break;
    430		default:
    431			break;
    432		}
    433		break;
    434	case 4:
    435		switch (clock) {
    436		case QE_CLK12:
    437			clock_bits = 6;
    438			break;
    439		case QE_CLK17:
    440			clock_bits = 7;
    441			break;
    442		default:
    443			break;
    444		}
    445		break;
    446	case 5:
    447		switch (clock) {
    448		case QE_CLK14:
    449			clock_bits = 6;
    450			break;
    451		case QE_CLK19:
    452			clock_bits = 7;
    453			break;
    454		default:
    455			break;
    456		}
    457		break;
    458	case 6:
    459		switch (clock) {
    460		case QE_CLK16:
    461			clock_bits = 6;
    462			break;
    463		case QE_CLK21:
    464			clock_bits = 7;
    465			break;
    466		default:
    467			break;
    468		}
    469		break;
    470	case 7:
    471		switch (clock) {
    472		case QE_CLK18:
    473			clock_bits = 6;
    474			break;
    475		case QE_CLK3:
    476			clock_bits = 7;
    477			break;
    478		default:
    479			break;
    480		}
    481		break;
    482	}
    483
    484	return clock_bits;
    485}
    486
    487/* tdm_num: TDM A-H port num is 0-7 */
    488static int ucc_get_tdm_rxtx_clk(enum comm_dir mode, u32 tdm_num,
    489				enum qe_clock clock)
    490{
    491	int clock_bits;
    492
    493	clock_bits = ucc_get_tdm_common_clk(tdm_num, clock);
    494	if (clock_bits > 0)
    495		return clock_bits;
    496	if (mode == COMM_DIR_RX)
    497		clock_bits = ucc_get_tdm_rx_clk(tdm_num, clock);
    498	if (mode == COMM_DIR_TX)
    499		clock_bits = ucc_get_tdm_tx_clk(tdm_num, clock);
    500	return clock_bits;
    501}
    502
    503static u32 ucc_get_tdm_clk_shift(enum comm_dir mode, u32 tdm_num)
    504{
    505	u32 shift;
    506
    507	shift = (mode == COMM_DIR_RX) ? RX_CLK_SHIFT_BASE : TX_CLK_SHIFT_BASE;
    508	if (tdm_num < 4)
    509		shift -= tdm_num * 4;
    510	else
    511		shift -= (tdm_num - 4) * 4;
    512
    513	return shift;
    514}
    515
    516int ucc_set_tdm_rxtx_clk(u32 tdm_num, enum qe_clock clock,
    517			 enum comm_dir mode)
    518{
    519	int clock_bits;
    520	u32 shift;
    521	struct qe_mux __iomem *qe_mux_reg;
    522	__be32 __iomem *cmxs1cr;
    523
    524	qe_mux_reg = &qe_immr->qmx;
    525
    526	if (tdm_num > 7)
    527		return -EINVAL;
    528
    529	/* The communications direction must be RX or TX */
    530	if (mode != COMM_DIR_RX && mode != COMM_DIR_TX)
    531		return -EINVAL;
    532
    533	clock_bits = ucc_get_tdm_rxtx_clk(mode, tdm_num, clock);
    534	if (clock_bits < 0)
    535		return -EINVAL;
    536
    537	shift = ucc_get_tdm_clk_shift(mode, tdm_num);
    538
    539	cmxs1cr = (tdm_num < 4) ? &qe_mux_reg->cmxsi1cr_l :
    540				  &qe_mux_reg->cmxsi1cr_h;
    541
    542	qe_clrsetbits_be32(cmxs1cr, QE_CMXUCR_TX_CLK_SRC_MASK << shift,
    543			   clock_bits << shift);
    544
    545	return 0;
    546}
    547
    548static int ucc_get_tdm_sync_source(u32 tdm_num, enum qe_clock clock,
    549				   enum comm_dir mode)
    550{
    551	int source = -EINVAL;
    552
    553	if (mode == COMM_DIR_RX && clock == QE_RSYNC_PIN) {
    554		source = 0;
    555		return source;
    556	}
    557	if (mode == COMM_DIR_TX && clock == QE_TSYNC_PIN) {
    558		source = 0;
    559		return source;
    560	}
    561
    562	switch (tdm_num) {
    563	case 0:
    564	case 1:
    565		switch (clock) {
    566		case QE_BRG9:
    567			source = 1;
    568			break;
    569		case QE_BRG10:
    570			source = 2;
    571			break;
    572		default:
    573			break;
    574		}
    575		break;
    576	case 2:
    577	case 3:
    578		switch (clock) {
    579		case QE_BRG9:
    580			source = 1;
    581			break;
    582		case QE_BRG11:
    583			source = 2;
    584			break;
    585		default:
    586			break;
    587		}
    588		break;
    589	case 4:
    590	case 5:
    591		switch (clock) {
    592		case QE_BRG13:
    593			source = 1;
    594			break;
    595		case QE_BRG14:
    596			source = 2;
    597			break;
    598		default:
    599			break;
    600		}
    601		break;
    602	case 6:
    603	case 7:
    604		switch (clock) {
    605		case QE_BRG13:
    606			source = 1;
    607			break;
    608		case QE_BRG15:
    609			source = 2;
    610			break;
    611		default:
    612			break;
    613		}
    614		break;
    615	}
    616
    617	return source;
    618}
    619
    620static u32 ucc_get_tdm_sync_shift(enum comm_dir mode, u32 tdm_num)
    621{
    622	u32 shift;
    623
    624	shift = (mode == COMM_DIR_RX) ? RX_SYNC_SHIFT_BASE : TX_SYNC_SHIFT_BASE;
    625	shift -= tdm_num * 2;
    626
    627	return shift;
    628}
    629
    630int ucc_set_tdm_rxtx_sync(u32 tdm_num, enum qe_clock clock,
    631			  enum comm_dir mode)
    632{
    633	int source;
    634	u32 shift;
    635	struct qe_mux __iomem *qe_mux_reg;
    636
    637	qe_mux_reg = &qe_immr->qmx;
    638
    639	if (tdm_num >= UCC_TDM_NUM)
    640		return -EINVAL;
    641
    642	/* The communications direction must be RX or TX */
    643	if (mode != COMM_DIR_RX && mode != COMM_DIR_TX)
    644		return -EINVAL;
    645
    646	source = ucc_get_tdm_sync_source(tdm_num, clock, mode);
    647	if (source < 0)
    648		return -EINVAL;
    649
    650	shift = ucc_get_tdm_sync_shift(mode, tdm_num);
    651
    652	qe_clrsetbits_be32(&qe_mux_reg->cmxsi1syr,
    653			   QE_CMXUCR_TX_CLK_SRC_MASK << shift,
    654			   source << shift);
    655
    656	return 0;
    657}