brintos

brintos / linux-shallow public Read only

0
0
Text · 6.4 KiB · 657783e Raw
240 lines · c
1// SPDX-License-Identifier: GPL-2.0-or-later2/*3 * Marvell 88E6xxx Switch Global 2 Registers support4 *5 * Copyright (c) 2008 Marvell Semiconductor6 *7 * Copyright (c) 2016-2017 Savoir-faire Linux Inc.8 *	Vivien Didelot <vivien.didelot@savoirfairelinux.com>9 *10 * Copyright (c) 2017 National Instruments11 *	Brandon Streiff <brandon.streiff@ni.com>12 */13 14#include <linux/bitfield.h>15 16#include "global2.h"17 18/* Offset 0x16: AVB Command Register19 * Offset 0x17: AVB Data Register20 *21 * There are two different versions of this register interface:22 *    "6352": 3-bit "op" field, 4-bit "port" field.23 *    "6390": 2-bit "op" field, 5-bit "port" field.24 *25 * The "op" codes are different between the two, as well as the special26 * port fields for global PTP and TAI configuration.27 */28 29/* mv88e6xxx_g2_avb_read -- Read one or multiple 16-bit words.30 * The hardware supports snapshotting up to four contiguous registers.31 */32static int mv88e6xxx_g2_avb_wait(struct mv88e6xxx_chip *chip)33{34	int bit = __bf_shf(MV88E6352_G2_AVB_CMD_BUSY);35 36	return mv88e6xxx_g2_wait_bit(chip, MV88E6352_G2_AVB_CMD, bit, 0);37}38 39static int mv88e6xxx_g2_avb_read(struct mv88e6xxx_chip *chip, u16 readop,40				 u16 *data, int len)41{42	int err;43	int i;44 45	err = mv88e6xxx_g2_avb_wait(chip);46	if (err)47		return err;48 49	/* Hardware can only snapshot four words. */50	if (len > 4)51		return -E2BIG;52 53	err = mv88e6xxx_g2_write(chip, MV88E6352_G2_AVB_CMD,54				 MV88E6352_G2_AVB_CMD_BUSY | readop);55	if (err)56		return err;57 58	err = mv88e6xxx_g2_avb_wait(chip);59	if (err)60		return err;61 62	for (i = 0; i < len; ++i) {63		err = mv88e6xxx_g2_read(chip, MV88E6352_G2_AVB_DATA,64					&data[i]);65		if (err)66			return err;67	}68 69	return 0;70}71 72/* mv88e6xxx_g2_avb_write -- Write one 16-bit word. */73static int mv88e6xxx_g2_avb_write(struct mv88e6xxx_chip *chip, u16 writeop,74				  u16 data)75{76	int err;77 78	err = mv88e6xxx_g2_avb_wait(chip);79	if (err)80		return err;81 82	err = mv88e6xxx_g2_write(chip, MV88E6352_G2_AVB_DATA, data);83	if (err)84		return err;85 86	err = mv88e6xxx_g2_write(chip, MV88E6352_G2_AVB_CMD,87				 MV88E6352_G2_AVB_CMD_BUSY | writeop);88 89	return mv88e6xxx_g2_avb_wait(chip);90}91 92static int mv88e6352_g2_avb_port_ptp_read(struct mv88e6xxx_chip *chip,93					  int port, int addr, u16 *data,94					  int len)95{96	u16 readop = (len == 1 ? MV88E6352_G2_AVB_CMD_OP_READ :97				 MV88E6352_G2_AVB_CMD_OP_READ_INCR) |98		     (port << 8) | (MV88E6352_G2_AVB_CMD_BLOCK_PTP << 5) |99		     addr;100 101	return mv88e6xxx_g2_avb_read(chip, readop, data, len);102}103 104static int mv88e6352_g2_avb_port_ptp_write(struct mv88e6xxx_chip *chip,105					   int port, int addr, u16 data)106{107	u16 writeop = MV88E6352_G2_AVB_CMD_OP_WRITE | (port << 8) |108		      (MV88E6352_G2_AVB_CMD_BLOCK_PTP << 5) | addr;109 110	return mv88e6xxx_g2_avb_write(chip, writeop, data);111}112 113static int mv88e6352_g2_avb_ptp_read(struct mv88e6xxx_chip *chip, int addr,114				     u16 *data, int len)115{116	return mv88e6352_g2_avb_port_ptp_read(chip,117					MV88E6352_G2_AVB_CMD_PORT_PTPGLOBAL,118					addr, data, len);119}120 121static int mv88e6352_g2_avb_ptp_write(struct mv88e6xxx_chip *chip, int addr,122				      u16 data)123{124	return mv88e6352_g2_avb_port_ptp_write(chip,125					MV88E6352_G2_AVB_CMD_PORT_PTPGLOBAL,126					addr, data);127}128 129static int mv88e6352_g2_avb_tai_read(struct mv88e6xxx_chip *chip, int addr,130				     u16 *data, int len)131{132	return mv88e6352_g2_avb_port_ptp_read(chip,133					MV88E6352_G2_AVB_CMD_PORT_TAIGLOBAL,134					addr, data, len);135}136 137static int mv88e6352_g2_avb_tai_write(struct mv88e6xxx_chip *chip, int addr,138				      u16 data)139{140	return mv88e6352_g2_avb_port_ptp_write(chip,141					MV88E6352_G2_AVB_CMD_PORT_TAIGLOBAL,142					addr, data);143}144 145const struct mv88e6xxx_avb_ops mv88e6352_avb_ops = {146	.port_ptp_read		= mv88e6352_g2_avb_port_ptp_read,147	.port_ptp_write		= mv88e6352_g2_avb_port_ptp_write,148	.ptp_read		= mv88e6352_g2_avb_ptp_read,149	.ptp_write		= mv88e6352_g2_avb_ptp_write,150	.tai_read		= mv88e6352_g2_avb_tai_read,151	.tai_write		= mv88e6352_g2_avb_tai_write,152};153 154static int mv88e6165_g2_avb_tai_read(struct mv88e6xxx_chip *chip, int addr,155				     u16 *data, int len)156{157	return mv88e6352_g2_avb_port_ptp_read(chip,158					MV88E6165_G2_AVB_CMD_PORT_PTPGLOBAL,159					addr, data, len);160}161 162static int mv88e6165_g2_avb_tai_write(struct mv88e6xxx_chip *chip, int addr,163				      u16 data)164{165	return mv88e6352_g2_avb_port_ptp_write(chip,166					MV88E6165_G2_AVB_CMD_PORT_PTPGLOBAL,167					addr, data);168}169 170const struct mv88e6xxx_avb_ops mv88e6165_avb_ops = {171	.port_ptp_read		= mv88e6352_g2_avb_port_ptp_read,172	.port_ptp_write		= mv88e6352_g2_avb_port_ptp_write,173	.ptp_read		= mv88e6352_g2_avb_ptp_read,174	.ptp_write		= mv88e6352_g2_avb_ptp_write,175	.tai_read		= mv88e6165_g2_avb_tai_read,176	.tai_write		= mv88e6165_g2_avb_tai_write,177};178 179static int mv88e6390_g2_avb_port_ptp_read(struct mv88e6xxx_chip *chip,180					  int port, int addr, u16 *data,181					  int len)182{183	u16 readop = (len == 1 ? MV88E6390_G2_AVB_CMD_OP_READ :184				 MV88E6390_G2_AVB_CMD_OP_READ_INCR) |185		     (port << 8) | (MV88E6352_G2_AVB_CMD_BLOCK_PTP << 5) |186		     addr;187 188	return mv88e6xxx_g2_avb_read(chip, readop, data, len);189}190 191static int mv88e6390_g2_avb_port_ptp_write(struct mv88e6xxx_chip *chip,192					   int port, int addr, u16 data)193{194	u16 writeop = MV88E6390_G2_AVB_CMD_OP_WRITE | (port << 8) |195		      (MV88E6352_G2_AVB_CMD_BLOCK_PTP << 5) | addr;196 197	return mv88e6xxx_g2_avb_write(chip, writeop, data);198}199 200static int mv88e6390_g2_avb_ptp_read(struct mv88e6xxx_chip *chip, int addr,201				     u16 *data, int len)202{203	return mv88e6390_g2_avb_port_ptp_read(chip,204					MV88E6390_G2_AVB_CMD_PORT_PTPGLOBAL,205					addr, data, len);206}207 208static int mv88e6390_g2_avb_ptp_write(struct mv88e6xxx_chip *chip, int addr,209				      u16 data)210{211	return mv88e6390_g2_avb_port_ptp_write(chip,212					MV88E6390_G2_AVB_CMD_PORT_PTPGLOBAL,213					addr, data);214}215 216static int mv88e6390_g2_avb_tai_read(struct mv88e6xxx_chip *chip, int addr,217				     u16 *data, int len)218{219	return mv88e6390_g2_avb_port_ptp_read(chip,220					MV88E6390_G2_AVB_CMD_PORT_TAIGLOBAL,221					addr, data, len);222}223 224static int mv88e6390_g2_avb_tai_write(struct mv88e6xxx_chip *chip, int addr,225				      u16 data)226{227	return mv88e6390_g2_avb_port_ptp_write(chip,228					MV88E6390_G2_AVB_CMD_PORT_TAIGLOBAL,229					addr, data);230}231 232const struct mv88e6xxx_avb_ops mv88e6390_avb_ops = {233	.port_ptp_read		= mv88e6390_g2_avb_port_ptp_read,234	.port_ptp_write		= mv88e6390_g2_avb_port_ptp_write,235	.ptp_read		= mv88e6390_g2_avb_ptp_read,236	.ptp_write		= mv88e6390_g2_avb_ptp_write,237	.tai_read		= mv88e6390_g2_avb_tai_read,238	.tai_write		= mv88e6390_g2_avb_tai_write,239};240