ocelot_io.c 2.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117
  1. // SPDX-License-Identifier: (GPL-2.0 OR MIT)
  2. /*
  3. * Microsemi Ocelot Switch driver
  4. *
  5. * Copyright (c) 2017 Microsemi Corporation
  6. */
  7. #include <linux/io.h>
  8. #include <linux/kernel.h>
  9. #include <linux/platform_device.h>
  10. #include "ocelot.h"
  11. u32 __ocelot_read_ix(struct ocelot *ocelot, u32 reg, u32 offset)
  12. {
  13. u16 target = reg >> TARGET_OFFSET;
  14. u32 val;
  15. WARN_ON(!target);
  16. regmap_read(ocelot->targets[target],
  17. ocelot->map[target][reg & REG_MASK] + offset, &val);
  18. return val;
  19. }
  20. EXPORT_SYMBOL(__ocelot_read_ix);
  21. void __ocelot_write_ix(struct ocelot *ocelot, u32 val, u32 reg, u32 offset)
  22. {
  23. u16 target = reg >> TARGET_OFFSET;
  24. WARN_ON(!target);
  25. regmap_write(ocelot->targets[target],
  26. ocelot->map[target][reg & REG_MASK] + offset, val);
  27. }
  28. EXPORT_SYMBOL(__ocelot_write_ix);
  29. void __ocelot_rmw_ix(struct ocelot *ocelot, u32 val, u32 mask, u32 reg,
  30. u32 offset)
  31. {
  32. u16 target = reg >> TARGET_OFFSET;
  33. WARN_ON(!target);
  34. regmap_update_bits(ocelot->targets[target],
  35. ocelot->map[target][reg & REG_MASK] + offset,
  36. mask, val);
  37. }
  38. EXPORT_SYMBOL(__ocelot_rmw_ix);
  39. u32 ocelot_port_readl(struct ocelot_port *port, u32 reg)
  40. {
  41. return readl(port->regs + reg);
  42. }
  43. EXPORT_SYMBOL(ocelot_port_readl);
  44. void ocelot_port_writel(struct ocelot_port *port, u32 val, u32 reg)
  45. {
  46. writel(val, port->regs + reg);
  47. }
  48. EXPORT_SYMBOL(ocelot_port_writel);
  49. int ocelot_regfields_init(struct ocelot *ocelot,
  50. const struct reg_field *const regfields)
  51. {
  52. unsigned int i;
  53. u16 target;
  54. for (i = 0; i < REGFIELD_MAX; i++) {
  55. struct reg_field regfield = {};
  56. u32 reg = regfields[i].reg;
  57. if (!reg)
  58. continue;
  59. target = regfields[i].reg >> TARGET_OFFSET;
  60. regfield.reg = ocelot->map[target][reg & REG_MASK];
  61. regfield.lsb = regfields[i].lsb;
  62. regfield.msb = regfields[i].msb;
  63. ocelot->regfields[i] =
  64. devm_regmap_field_alloc(ocelot->dev,
  65. ocelot->targets[target],
  66. regfield);
  67. if (IS_ERR(ocelot->regfields[i]))
  68. return PTR_ERR(ocelot->regfields[i]);
  69. }
  70. return 0;
  71. }
  72. EXPORT_SYMBOL(ocelot_regfields_init);
  73. static struct regmap_config ocelot_regmap_config = {
  74. .reg_bits = 32,
  75. .val_bits = 32,
  76. .reg_stride = 4,
  77. };
  78. struct regmap *ocelot_io_platform_init(struct ocelot *ocelot,
  79. struct platform_device *pdev,
  80. const char *name)
  81. {
  82. struct resource *res;
  83. void __iomem *regs;
  84. res = platform_get_resource_byname(pdev, IORESOURCE_MEM, name);
  85. regs = devm_ioremap_resource(ocelot->dev, res);
  86. if (IS_ERR(regs))
  87. return ERR_CAST(regs);
  88. ocelot_regmap_config.name = name;
  89. return devm_regmap_init_mmio(ocelot->dev, regs,
  90. &ocelot_regmap_config);
  91. }
  92. EXPORT_SYMBOL(ocelot_io_platform_init);