port_hidden.c 1.9 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071
  1. // SPDX-License-Identifier: GPL-2.0-or-later
  2. /*
  3. * Marvell 88E6xxx Switch Hidden Registers support
  4. *
  5. * Copyright (c) 2008 Marvell Semiconductor
  6. *
  7. * Copyright (c) 2019 Andrew Lunn <andrew@lunn.ch>
  8. */
  9. #include <linux/bitfield.h>
  10. #include "chip.h"
  11. #include "port.h"
  12. /* The mv88e6390 and mv88e6341 have some hidden registers used for debug and
  13. * development. The errata also makes use of them.
  14. */
  15. int mv88e6xxx_port_hidden_write(struct mv88e6xxx_chip *chip, int block,
  16. int port, int reg, u16 val)
  17. {
  18. u16 ctrl;
  19. int err;
  20. err = mv88e6xxx_port_write(chip, MV88E6XXX_PORT_RESERVED_1A_DATA_PORT,
  21. MV88E6XXX_PORT_RESERVED_1A, val);
  22. if (err)
  23. return err;
  24. ctrl = MV88E6XXX_PORT_RESERVED_1A_BUSY |
  25. MV88E6XXX_PORT_RESERVED_1A_WRITE |
  26. block << MV88E6XXX_PORT_RESERVED_1A_BLOCK_SHIFT |
  27. port << MV88E6XXX_PORT_RESERVED_1A_PORT_SHIFT |
  28. reg;
  29. return mv88e6xxx_port_write(chip, MV88E6XXX_PORT_RESERVED_1A_CTRL_PORT,
  30. MV88E6XXX_PORT_RESERVED_1A, ctrl);
  31. }
  32. int mv88e6xxx_port_hidden_wait(struct mv88e6xxx_chip *chip)
  33. {
  34. int bit = __bf_shf(MV88E6XXX_PORT_RESERVED_1A_BUSY);
  35. return mv88e6xxx_port_wait_bit(chip,
  36. MV88E6XXX_PORT_RESERVED_1A_CTRL_PORT,
  37. MV88E6XXX_PORT_RESERVED_1A, bit, 0);
  38. }
  39. int mv88e6xxx_port_hidden_read(struct mv88e6xxx_chip *chip, int block, int port,
  40. int reg, u16 *val)
  41. {
  42. u16 ctrl;
  43. int err;
  44. ctrl = MV88E6XXX_PORT_RESERVED_1A_BUSY |
  45. MV88E6XXX_PORT_RESERVED_1A_READ |
  46. block << MV88E6XXX_PORT_RESERVED_1A_BLOCK_SHIFT |
  47. port << MV88E6XXX_PORT_RESERVED_1A_PORT_SHIFT |
  48. reg;
  49. err = mv88e6xxx_port_write(chip, MV88E6XXX_PORT_RESERVED_1A_CTRL_PORT,
  50. MV88E6XXX_PORT_RESERVED_1A, ctrl);
  51. if (err)
  52. return err;
  53. err = mv88e6xxx_port_hidden_wait(chip);
  54. if (err)
  55. return err;
  56. return mv88e6xxx_port_read(chip, MV88E6XXX_PORT_RESERVED_1A_DATA_PORT,
  57. MV88E6XXX_PORT_RESERVED_1A, val);
  58. }