summaryrefslogtreecommitdiff
path: root/drivers/staging/hikey9xx
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/staging/hikey9xx')
-rw-r--r--drivers/staging/hikey9xx/Kconfig22
-rw-r--r--drivers/staging/hikey9xx/Makefile3
-rw-r--r--drivers/staging/hikey9xx/hi6421-spmi-pmic.c116
-rw-r--r--drivers/staging/hikey9xx/hisi-spmi-controller.c367
-rw-r--r--drivers/staging/hikey9xx/hisilicon,hi6421-spmi-pmic.yaml7
-rw-r--r--drivers/staging/hikey9xx/hisilicon,hisi-spmi-controller.yaml71
-rw-r--r--drivers/staging/hikey9xx/phy-hi3670-usb3.c668
-rw-r--r--drivers/staging/hikey9xx/phy-hi3670-usb3.yaml73
8 files changed, 68 insertions, 1259 deletions
diff --git a/drivers/staging/hikey9xx/Kconfig b/drivers/staging/hikey9xx/Kconfig
index c4dc1016edf2..9f53df9068fe 100644
--- a/drivers/staging/hikey9xx/Kconfig
+++ b/drivers/staging/hikey9xx/Kconfig
@@ -1,27 +1,5 @@
# SPDX-License-Identifier: GPL-2.0
-# to be placed at drivers/phy
-config PHY_HI3670_USB
- tristate "hi3670 USB PHY support"
- depends on (ARCH_HISI && ARM64) || COMPILE_TEST
- select GENERIC_PHY
- select MFD_SYSCON
- help
- Enable this to support the HISILICON HI3670 USB PHY.
-
- To compile this driver as a module, choose M here.
-
-# to be placed at drivers/spmi
-config SPMI_HISI3670
- tristate "Hisilicon 3670 SPMI Controller"
- select IRQ_DOMAIN_HIERARCHY
- depends on HAS_IOMEM
- depends on SPMI
- help
- If you say yes to this option, support will be included for the
- built-in SPMI PMIC Arbiter interface on Hisilicon 3670
- processors.
-
# to be placed at drivers/mfd
config MFD_HI6421_SPMI
tristate "HiSilicon Hi6421v600 SPMI PMU/Codec IC"
diff --git a/drivers/staging/hikey9xx/Makefile b/drivers/staging/hikey9xx/Makefile
index 9103735d8377..e3108d7dd849 100644
--- a/drivers/staging/hikey9xx/Makefile
+++ b/drivers/staging/hikey9xx/Makefile
@@ -1,6 +1,3 @@
# SPDX-License-Identifier: GPL-2.0
-obj-$(CONFIG_PHY_HI3670_USB) += phy-hi3670-usb3.o
-
-obj-$(CONFIG_SPMI_HISI3670) += hisi-spmi-controller.o
obj-$(CONFIG_MFD_HI6421_SPMI) += hi6421-spmi-pmic.o
diff --git a/drivers/staging/hikey9xx/hi6421-spmi-pmic.c b/drivers/staging/hikey9xx/hi6421-spmi-pmic.c
index 626140cb96f2..35ef3d4c760b 100644
--- a/drivers/staging/hikey9xx/hi6421-spmi-pmic.c
+++ b/drivers/staging/hikey9xx/hi6421-spmi-pmic.c
@@ -33,17 +33,27 @@ enum hi6421_spmi_pmic_irq_list {
SIM0_HPD_F,
SIM1_HPD_R,
SIM1_HPD_F,
- PMIC_IRQ_LIST_MAX,
+
+ PMIC_IRQ_LIST_MAX
};
-#define HISI_IRQ_ARRAY 2
-#define HISI_IRQ_NUM (HISI_IRQ_ARRAY * 8)
+#define HISI_IRQ_BANK_SIZE 2
-#define HISI_IRQ_KEY_NUM 0
+/*
+ * IRQ number for the power key button and mask for both UP and DOWN IRQs
+ */
+#define HISI_POWERKEY_IRQ_NUM 0
+#define HISI_IRQ_POWERKEY_UP_DOWN (BIT(POWERKEY_DOWN) | BIT(POWERKEY_UP))
-#define HISI_BITS 8
-#define HISI_IRQ_KEY_VALUE (BIT(POWERKEY_DOWN) | BIT(POWERKEY_UP))
-#define HISI_MASK GENMASK(HISI_BITS - 1, 0)
+/*
+ * Registers for IRQ address and IRQ mask bits
+ *
+ * Please notice that we need to regmap a larger region, as other
+ * registers are used by the regulators.
+ * See drivers/regulator/hi6421-regulator.c.
+ */
+#define SOC_PMIC_IRQ_MASK_0_ADDR 0x0202
+#define SOC_PMIC_IRQ0_ADDR 0x0212
/*
* The IRQs are mapped as:
@@ -67,13 +77,14 @@ enum hi6421_spmi_pmic_irq_list {
* SIM1_HPD_R 0x0203 0x213 bit 4
* SIM1_HPD_F 0x0203 0x213 bit 5
* ====================== ============= ============ =====
+ *
+ * Each mask register contains 8 bits. The ancillary macros below
+ * convert a number from 0 to 14 into a register address and a bit mask
*/
-#define SOC_PMIC_IRQ_MASK_0_ADDR 0x0202
-#define SOC_PMIC_IRQ0_ADDR 0x0212
-
-#define IRQ_MASK_REGISTER(irq_data) (SOC_PMIC_IRQ_MASK_0_ADDR + \
- (irqd_to_hwirq(irq_data) >> 3))
-#define IRQ_MASK_BIT(irq_data) BIT(irqd_to_hwirq(irq_data) & 0x07)
+#define HISI_IRQ_MASK_REG(irq_data) (SOC_PMIC_IRQ_MASK_0_ADDR + \
+ (irqd_to_hwirq(irq_data) / BITS_PER_BYTE))
+#define HISI_IRQ_MASK_BIT(irq_data) BIT(irqd_to_hwirq(irq_data) & (BITS_PER_BYTE - 1))
+#define HISI_8BITS_MASK 0xff
static const struct mfd_cell hi6421v600_devs[] = {
{ .name = "hi6421v600-regulator", },
@@ -86,23 +97,31 @@ static irqreturn_t hi6421_spmi_irq_handler(int irq, void *priv)
unsigned int in;
int i, offset;
- for (i = 0; i < HISI_IRQ_ARRAY; i++) {
+ for (i = 0; i < HISI_IRQ_BANK_SIZE; i++) {
regmap_read(ddata->regmap, SOC_PMIC_IRQ0_ADDR + i, &in);
- pending = HISI_MASK & in;
- regmap_write(ddata->regmap, SOC_PMIC_IRQ0_ADDR + i, pending);
- if (i == HISI_IRQ_KEY_NUM &&
- (pending & HISI_IRQ_KEY_VALUE) == HISI_IRQ_KEY_VALUE) {
+ /* Mark pending IRQs as handled */
+ regmap_write(ddata->regmap, SOC_PMIC_IRQ0_ADDR + i, in);
+
+ pending = in & HISI_8BITS_MASK;
+
+ if (i == HISI_POWERKEY_IRQ_NUM &&
+ (pending & HISI_IRQ_POWERKEY_UP_DOWN) == HISI_IRQ_POWERKEY_UP_DOWN) {
+ /*
+ * If both powerkey down and up IRQs are received,
+ * handle them at the right order
+ */
generic_handle_irq(ddata->irqs[POWERKEY_DOWN]);
generic_handle_irq(ddata->irqs[POWERKEY_UP]);
- pending &= (~HISI_IRQ_KEY_VALUE);
+ pending &= ~HISI_IRQ_POWERKEY_UP_DOWN;
}
if (!pending)
continue;
- for_each_set_bit(offset, &pending, HISI_BITS)
- generic_handle_irq(ddata->irqs[offset + i * HISI_BITS]);
+ for_each_set_bit(offset, &pending, BITS_PER_BYTE) {
+ generic_handle_irq(ddata->irqs[offset + i * BITS_PER_BYTE]);
+ }
}
return IRQ_HANDLED;
@@ -115,12 +134,12 @@ static void hi6421_spmi_irq_mask(struct irq_data *d)
unsigned int data;
u32 offset;
- offset = IRQ_MASK_REGISTER(d);
+ offset = HISI_IRQ_MASK_REG(d);
spin_lock_irqsave(&ddata->lock, flags);
regmap_read(ddata->regmap, offset, &data);
- data |= IRQ_MASK_BIT(d);
+ data |= HISI_IRQ_MASK_BIT(d);
regmap_write(ddata->regmap, offset, data);
spin_unlock_irqrestore(&ddata->lock, flags);
@@ -132,20 +151,19 @@ static void hi6421_spmi_irq_unmask(struct irq_data *d)
u32 data, offset;
unsigned long flags;
- offset = (irqd_to_hwirq(d) >> 3);
- offset += SOC_PMIC_IRQ_MASK_0_ADDR;
+ offset = HISI_IRQ_MASK_REG(d);
spin_lock_irqsave(&ddata->lock, flags);
regmap_read(ddata->regmap, offset, &data);
- data &= ~(1 << (irqd_to_hwirq(d) & 0x07));
+ data &= ~HISI_IRQ_MASK_BIT(d);
regmap_write(ddata->regmap, offset, data);
spin_unlock_irqrestore(&ddata->lock, flags);
}
static struct irq_chip hi6421_spmi_pmu_irqchip = {
- .name = "hisi-irq",
+ .name = "hi6421v600-irq",
.irq_mask = hi6421_spmi_irq_mask,
.irq_unmask = hi6421_spmi_irq_unmask,
.irq_disable = hi6421_spmi_irq_mask,
@@ -158,7 +176,7 @@ static int hi6421_spmi_irq_map(struct irq_domain *d, unsigned int virq,
struct hi6421_spmi_pmic *ddata = d->host_data;
irq_set_chip_and_handler_name(virq, &hi6421_spmi_pmu_irqchip,
- handle_simple_irq, "hisi");
+ handle_simple_irq, "hi6421v600");
irq_set_chip_data(virq, ddata);
irq_set_irq_type(virq, IRQ_TYPE_NONE);
@@ -175,22 +193,24 @@ static void hi6421_spmi_pmic_irq_init(struct hi6421_spmi_pmic *ddata)
int i;
unsigned int pending;
- for (i = 0; i < HISI_IRQ_ARRAY; i++)
+ /* Mask all IRQs */
+ for (i = 0; i < HISI_IRQ_BANK_SIZE; i++)
regmap_write(ddata->regmap, SOC_PMIC_IRQ_MASK_0_ADDR + i,
- HISI_MASK);
+ HISI_8BITS_MASK);
- for (i = 0; i < HISI_IRQ_ARRAY; i++) {
+ /* Mark all IRQs as handled */
+ for (i = 0; i < HISI_IRQ_BANK_SIZE; i++) {
regmap_read(ddata->regmap, SOC_PMIC_IRQ0_ADDR + i, &pending);
regmap_write(ddata->regmap, SOC_PMIC_IRQ0_ADDR + i,
- HISI_MASK);
+ HISI_8BITS_MASK);
}
}
static const struct regmap_config regmap_config = {
- .reg_bits = 16,
- .val_bits = HISI_BITS,
- .max_register = 0xffff,
- .fast_io = true
+ .reg_bits = 16,
+ .val_bits = BITS_PER_BYTE,
+ .max_register = 0xffff,
+ .fast_io = true
};
static int hi6421_spmi_pmic_probe(struct spmi_device *pdev)
@@ -230,29 +250,31 @@ static int hi6421_spmi_pmic_probe(struct spmi_device *pdev)
hi6421_spmi_pmic_irq_init(ddata);
- ddata->irqs = devm_kzalloc(dev, HISI_IRQ_NUM * sizeof(int), GFP_KERNEL);
+ ddata->irqs = devm_kzalloc(dev, PMIC_IRQ_LIST_MAX * sizeof(int), GFP_KERNEL);
if (!ddata->irqs)
return -ENOMEM;
- ddata->domain = irq_domain_add_simple(np, HISI_IRQ_NUM, 0,
+ ddata->domain = irq_domain_add_simple(np, PMIC_IRQ_LIST_MAX, 0,
&hi6421_spmi_domain_ops, ddata);
if (!ddata->domain) {
dev_err(dev, "Failed to create IRQ domain\n");
return -ENODEV;
}
- for (i = 0; i < HISI_IRQ_NUM; i++) {
+ for (i = 0; i < PMIC_IRQ_LIST_MAX; i++) {
virq = irq_create_mapping(ddata->domain, i);
if (!virq) {
dev_err(dev, "Failed to map H/W IRQ\n");
- return -ENOSPC;
+ return -ENODEV;
}
ddata->irqs[i] = virq;
}
- ret = request_threaded_irq(ddata->irq, hi6421_spmi_irq_handler, NULL,
- IRQF_TRIGGER_LOW | IRQF_SHARED | IRQF_NO_SUSPEND,
- "pmic", ddata);
+ ret = devm_request_threaded_irq(dev,
+ ddata->irq, hi6421_spmi_irq_handler,
+ NULL,
+ IRQF_TRIGGER_LOW | IRQF_SHARED | IRQF_NO_SUSPEND,
+ "pmic", ddata);
if (ret < 0) {
dev_err(dev, "Failed to start IRQ handling thread: error %d\n",
ret);
@@ -270,13 +292,6 @@ static int hi6421_spmi_pmic_probe(struct spmi_device *pdev)
return ret;
}
-static void hi6421_spmi_pmic_remove(struct spmi_device *pdev)
-{
- struct hi6421_spmi_pmic *ddata = dev_get_drvdata(&pdev->dev);
-
- free_irq(ddata->irq, ddata);
-}
-
static const struct of_device_id pmic_spmi_id_table[] = {
{ .compatible = "hisilicon,hi6421-spmi" },
{ }
@@ -289,7 +304,6 @@ static struct spmi_driver hi6421_spmi_pmic_driver = {
.of_match_table = pmic_spmi_id_table,
},
.probe = hi6421_spmi_pmic_probe,
- .remove = hi6421_spmi_pmic_remove,
};
module_spmi_driver(hi6421_spmi_pmic_driver);
diff --git a/drivers/staging/hikey9xx/hisi-spmi-controller.c b/drivers/staging/hikey9xx/hisi-spmi-controller.c
deleted file mode 100644
index 0d42bc65f39b..000000000000
--- a/drivers/staging/hikey9xx/hisi-spmi-controller.c
+++ /dev/null
@@ -1,367 +0,0 @@
-// SPDX-License-Identifier: GPL-2.0
-
-#include <linux/delay.h>
-#include <linux/err.h>
-#include <linux/interrupt.h>
-#include <linux/io.h>
-#include <linux/kernel.h>
-#include <linux/module.h>
-#include <linux/of.h>
-#include <linux/platform_device.h>
-#include <linux/seq_file.h>
-#include <linux/slab.h>
-#include <linux/spmi.h>
-
-/*
- * SPMI register addr
- */
-#define SPMI_CHANNEL_OFFSET 0x0300
-#define SPMI_SLAVE_OFFSET 0x20
-
-#define SPMI_APB_SPMI_CMD_BASE_ADDR 0x0100
-
-#define SPMI_APB_SPMI_WDATA0_BASE_ADDR 0x0104
-#define SPMI_APB_SPMI_WDATA1_BASE_ADDR 0x0108
-#define SPMI_APB_SPMI_WDATA2_BASE_ADDR 0x010c
-#define SPMI_APB_SPMI_WDATA3_BASE_ADDR 0x0110
-
-#define SPMI_APB_SPMI_STATUS_BASE_ADDR 0x0200
-
-#define SPMI_APB_SPMI_RDATA0_BASE_ADDR 0x0204
-#define SPMI_APB_SPMI_RDATA1_BASE_ADDR 0x0208
-#define SPMI_APB_SPMI_RDATA2_BASE_ADDR 0x020c
-#define SPMI_APB_SPMI_RDATA3_BASE_ADDR 0x0210
-
-#define SPMI_PER_DATAREG_BYTE 4
-/*
- * SPMI cmd register
- */
-#define SPMI_APB_SPMI_CMD_EN BIT(31)
-#define SPMI_APB_SPMI_CMD_TYPE_OFFSET 24
-#define SPMI_APB_SPMI_CMD_LENGTH_OFFSET 20
-#define SPMI_APB_SPMI_CMD_SLAVEID_OFFSET 16
-#define SPMI_APB_SPMI_CMD_ADDR_OFFSET 0
-
-/* Command Opcodes */
-
-enum spmi_controller_cmd_op_code {
- SPMI_CMD_REG_ZERO_WRITE = 0,
- SPMI_CMD_REG_WRITE = 1,
- SPMI_CMD_REG_READ = 2,
- SPMI_CMD_EXT_REG_WRITE = 3,
- SPMI_CMD_EXT_REG_READ = 4,
- SPMI_CMD_EXT_REG_WRITE_L = 5,
- SPMI_CMD_EXT_REG_READ_L = 6,
- SPMI_CMD_REG_RESET = 7,
- SPMI_CMD_REG_SLEEP = 8,
- SPMI_CMD_REG_SHUTDOWN = 9,
- SPMI_CMD_REG_WAKEUP = 10,
-};
-
-/*
- * SPMI status register
- */
-#define SPMI_APB_TRANS_DONE BIT(0)
-#define SPMI_APB_TRANS_FAIL BIT(2)
-
-/* Command register fields */
-#define SPMI_CONTROLLER_CMD_MAX_BYTE_COUNT 16
-
-/* Maximum number of support PMIC peripherals */
-#define SPMI_CONTROLLER_TIMEOUT_US 1000
-#define SPMI_CONTROLLER_MAX_TRANS_BYTES 16
-
-struct spmi_controller_dev {
- struct spmi_controller *controller;
- struct device *dev;
- void __iomem *base;
- spinlock_t lock;
- u32 channel;
-};
-
-static int spmi_controller_wait_for_done(struct device *dev,
- struct spmi_controller_dev *ctrl_dev,
- void __iomem *base, u8 sid, u16 addr)
-{
- u32 timeout = SPMI_CONTROLLER_TIMEOUT_US;
- u32 status, offset;
-
- offset = SPMI_APB_SPMI_STATUS_BASE_ADDR;
- offset += SPMI_CHANNEL_OFFSET * ctrl_dev->channel + SPMI_SLAVE_OFFSET * sid;
-
- do {
- status = readl(base + offset);
-
- if (status & SPMI_APB_TRANS_DONE) {
- if (status & SPMI_APB_TRANS_FAIL) {
- dev_err(dev, "%s: transaction failed (0x%x)\n",
- __func__, status);
- return -EIO;
- }
- dev_dbg(dev, "%s: status 0x%x\n", __func__, status);
- return 0;
- }
- udelay(1);
- } while (timeout--);
-
- dev_err(dev, "%s: timeout, status 0x%x\n", __func__, status);
- return -ETIMEDOUT;
-}
-
-static int spmi_read_cmd(struct spmi_controller *ctrl,
- u8 opc, u8 slave_id, u16 slave_addr, u8 *__buf, size_t bc)
-{
- struct spmi_controller_dev *spmi_controller = dev_get_drvdata(&ctrl->dev);
- u32 chnl_ofst = SPMI_CHANNEL_OFFSET * spmi_controller->channel;
- unsigned long flags;
- u8 *buf = __buf;
- u32 cmd, data;
- int rc;
- u8 op_code, i;
-
- if (bc > SPMI_CONTROLLER_MAX_TRANS_BYTES) {
- dev_err(&ctrl->dev,
- "spmi_controller supports 1..%d bytes per trans, but:%zu requested\n",
- SPMI_CONTROLLER_MAX_TRANS_BYTES, bc);
- return -EINVAL;
- }
-
- switch (opc) {
- case SPMI_CMD_READ:
- op_code = SPMI_CMD_REG_READ;
- break;
- case SPMI_CMD_EXT_READ:
- op_code = SPMI_CMD_EXT_REG_READ;
- break;
- case SPMI_CMD_EXT_READL:
- op_code = SPMI_CMD_EXT_REG_READ_L;
- break;
- default:
- dev_err(&ctrl->dev, "invalid read cmd 0x%x\n", opc);
- return -EINVAL;
- }
-
- cmd = SPMI_APB_SPMI_CMD_EN |
- (op_code << SPMI_APB_SPMI_CMD_TYPE_OFFSET) |
- ((bc - 1) << SPMI_APB_SPMI_CMD_LENGTH_OFFSET) |
- ((slave_id & 0xf) << SPMI_APB_SPMI_CMD_SLAVEID_OFFSET) | /* slvid */
- ((slave_addr & 0xffff) << SPMI_APB_SPMI_CMD_ADDR_OFFSET); /* slave_addr */
-
- spin_lock_irqsave(&spmi_controller->lock, flags);
-
- writel(cmd, spmi_controller->base + chnl_ofst + SPMI_APB_SPMI_CMD_BASE_ADDR);
-
- rc = spmi_controller_wait_for_done(&ctrl->dev, spmi_controller,
- spmi_controller->base, slave_id, slave_addr);
- if (rc)
- goto done;
-
- for (i = 0; bc > i * SPMI_PER_DATAREG_BYTE; i++) {
- data = readl(spmi_controller->base + chnl_ofst +
- SPMI_SLAVE_OFFSET * slave_id +
- SPMI_APB_SPMI_RDATA0_BASE_ADDR +
- i * SPMI_PER_DATAREG_BYTE);
- data = be32_to_cpu((__be32 __force)data);
- if ((bc - i * SPMI_PER_DATAREG_BYTE) >> 2) {
- memcpy(buf, &data, sizeof(data));
- buf += sizeof(data);
- } else {
- memcpy(buf, &data, bc % SPMI_PER_DATAREG_BYTE);
- buf += (bc % SPMI_PER_DATAREG_BYTE);
- }
- }
-
-done:
- spin_unlock_irqrestore(&spmi_controller->lock, flags);
- if (rc)
- dev_err(&ctrl->dev,
- "spmi read wait timeout op:0x%x slave_id:%d slave_addr:0x%x bc:%zu\n",
- opc, slave_id, slave_addr, bc + 1);
- else
- dev_dbg(&ctrl->dev, "%s: id:%d slave_addr:0x%x, read value: %*ph\n",
- __func__, slave_id, slave_addr, (int)bc, __buf);
-
- return rc;
-}
-
-static int spmi_write_cmd(struct spmi_controller *ctrl,
- u8 opc, u8 slave_id, u16 slave_addr, const u8 *__buf, size_t bc)
-{
- struct spmi_controller_dev *spmi_controller = dev_get_drvdata(&ctrl->dev);
- u32 chnl_ofst = SPMI_CHANNEL_OFFSET * spmi_controller->channel;
- const u8 *buf = __buf;
- unsigned long flags;
- u32 cmd, data;
- int rc;
- u8 op_code, i;
-
- if (bc > SPMI_CONTROLLER_MAX_TRANS_BYTES) {
- dev_err(&ctrl->dev,
- "spmi_controller supports 1..%d bytes per trans, but:%zu requested\n",
- SPMI_CONTROLLER_MAX_TRANS_BYTES, bc);
- return -EINVAL;
- }
-
- switch (opc) {
- case SPMI_CMD_WRITE:
- op_code = SPMI_CMD_REG_WRITE;
- break;
- case SPMI_CMD_EXT_WRITE:
- op_code = SPMI_CMD_EXT_REG_WRITE;
- break;
- case SPMI_CMD_EXT_WRITEL:
- op_code = SPMI_CMD_EXT_REG_WRITE_L;
- break;
- default:
- dev_err(&ctrl->dev, "invalid write cmd 0x%x\n", opc);
- return -EINVAL;
- }
-
- cmd = SPMI_APB_SPMI_CMD_EN |
- (op_code << SPMI_APB_SPMI_CMD_TYPE_OFFSET) |
- ((bc - 1) << SPMI_APB_SPMI_CMD_LENGTH_OFFSET) |
- ((slave_id & 0xf) << SPMI_APB_SPMI_CMD_SLAVEID_OFFSET) |
- ((slave_addr & 0xffff) << SPMI_APB_SPMI_CMD_ADDR_OFFSET);
-
- /* Write data to FIFOs */
- spin_lock_irqsave(&spmi_controller->lock, flags);
-
- for (i = 0; bc > i * SPMI_PER_DATAREG_BYTE; i++) {
- data = 0;
- if ((bc - i * SPMI_PER_DATAREG_BYTE) >> 2) {
- memcpy(&data, buf, sizeof(data));
- buf += sizeof(data);
- } else {
- memcpy(&data, buf, bc % SPMI_PER_DATAREG_BYTE);
- buf += (bc % SPMI_PER_DATAREG_BYTE);
- }
-
- writel((u32 __force)cpu_to_be32(data),
- spmi_controller->base + chnl_ofst +
- SPMI_APB_SPMI_WDATA0_BASE_ADDR +
- SPMI_PER_DATAREG_BYTE * i);
- }
-
- /* Start the transaction */
- writel(cmd, spmi_controller->base + chnl_ofst + SPMI_APB_SPMI_CMD_BASE_ADDR);
-
- rc = spmi_controller_wait_for_done(&ctrl->dev, spmi_controller,
- spmi_controller->base, slave_id,
- slave_addr);
- spin_unlock_irqrestore(&spmi_controller->lock, flags);
-
- if (rc)
- dev_err(&ctrl->dev, "spmi write wait timeout op:0x%x slave_id:%d slave_addr:0x%x bc:%zu\n",
- opc, slave_id, slave_addr, bc);
- else
- dev_dbg(&ctrl->dev, "%s: id:%d slave_addr:0x%x, wrote value: %*ph\n",
- __func__, slave_id, slave_addr, (int)bc, __buf);
-
- return rc;
-}
-
-static int spmi_controller_probe(struct platform_device *pdev)
-{
- struct spmi_controller_dev *spmi_controller;
- struct spmi_controller *ctrl;
- struct resource *iores;
- int ret;
-
- ctrl = spmi_controller_alloc(&pdev->dev, sizeof(*spmi_controller));
- if (!ctrl) {
- dev_err(&pdev->dev, "can not allocate spmi_controller data\n");
- return -ENOMEM;
- }
- spmi_controller = spmi_controller_get_drvdata(ctrl);
- spmi_controller->controller = ctrl;
-
- iores = platform_get_resource(pdev, IORESOURCE_MEM, 0);
- if (!iores) {
- dev_err(&pdev->dev, "can not get resource!\n");
- ret = -EINVAL;
- goto err_put_controller;
- }
-
- spmi_controller->base = devm_ioremap(&pdev->dev, iores->start,
- resource_size(iores));
- if (!spmi_controller->base) {
- dev_err(&pdev->dev, "can not remap base addr!\n");
- ret = -EADDRNOTAVAIL;
- goto err_put_controller;
- }
-
- ret = of_property_read_u32(pdev->dev.of_node, "spmi-channel",
- &spmi_controller->channel);
- if (ret) {
- dev_err(&pdev->dev, "can not get channel\n");
- ret = -ENODEV;
- goto err_put_controller;
- }
-
- platform_set_drvdata(pdev, spmi_controller);
- dev_set_drvdata(&ctrl->dev, spmi_controller);
-
- spin_lock_init(&spmi_controller->lock);
-
- ctrl->nr = spmi_controller->channel;
- ctrl->dev.parent = pdev->dev.parent;
- ctrl->dev.of_node = of_node_get(pdev->dev.of_node);
-
- /* Callbacks */
- ctrl->read_cmd = spmi_read_cmd;
- ctrl->write_cmd = spmi_write_cmd;
-
- ret = spmi_controller_add(ctrl);
- if (ret) {
- dev_err(&pdev->dev, "spmi_controller_add failed with error %d!\n", ret);
- goto err_put_controller;
- }
-
- return 0;
-
-err_put_controller:
- spmi_controller_put(ctrl);
- return ret;
-}
-
-static int spmi_del_controller(struct platform_device *pdev)
-{
- struct spmi_controller *ctrl = platform_get_drvdata(pdev);
-
- spmi_controller_remove(ctrl);
- spmi_controller_put(ctrl);
- return 0;
-}
-
-static const struct of_device_id spmi_controller_match_table[] = {
- {
- .compatible = "hisilicon,kirin970-spmi-controller",
- },
- {}
-};
-MODULE_DEVICE_TABLE(of, spmi_controller_match_table);
-
-static struct platform_driver spmi_controller_driver = {
- .probe = spmi_controller_probe,
- .remove = spmi_del_controller,
- .driver = {
- .name = "hisi_spmi_controller",
- .of_match_table = spmi_controller_match_table,
- },
-};
-
-static int __init spmi_controller_init(void)
-{
- return platform_driver_register(&spmi_controller_driver);
-}
-postcore_initcall(spmi_controller_init);
-
-static void __exit spmi_controller_exit(void)
-{
- platform_driver_unregister(&spmi_controller_driver);
-}
-module_exit(spmi_controller_exit);
-
-MODULE_LICENSE("GPL v2");
-MODULE_VERSION("1.0");
-MODULE_ALIAS("platform:spmi_controller");
diff --git a/drivers/staging/hikey9xx/hisilicon,hi6421-spmi-pmic.yaml b/drivers/staging/hikey9xx/hisilicon,hi6421-spmi-pmic.yaml
index 3b23ad56b31a..8e355cddd437 100644
--- a/drivers/staging/hikey9xx/hisilicon,hi6421-spmi-pmic.yaml
+++ b/drivers/staging/hikey9xx/hisilicon,hi6421-spmi-pmic.yaml
@@ -17,7 +17,7 @@ description: |
node.
The SPMI controller part is provided by
- drivers/staging/hikey9xx/hisilicon,hisi-spmi-controller.yaml.
+ Documentation/devicetree/bindings/mfd/hisilicon,hi6421-spmi-pmic.yaml
properties:
$nodename:
@@ -32,12 +32,11 @@ properties:
'#interrupt-cells':
const: 2
- interrupt-controller:
- description:
- Identify that the PMIC is capable of behaving as an interrupt controller.
+ interrupt-controller: true
gpios:
maxItems: 1
+ description: GPIO used for IRQs
regulators:
type: object
diff --git a/drivers/staging/hikey9xx/hisilicon,hisi-spmi-controller.yaml b/drivers/staging/hikey9xx/hisilicon,hisi-spmi-controller.yaml
deleted file mode 100644
index 6b755039a74c..000000000000
--- a/drivers/staging/hikey9xx/hisilicon,hisi-spmi-controller.yaml
+++ /dev/null
@@ -1,71 +0,0 @@
-# SPDX-License-Identifier: GPL-2.0
-%YAML 1.2
----
-$id: http://devicetree.org/schemas/spmi/hisilicon,hisi-spmi-controller.yaml#
-$schema: http://devicetree.org/meta-schemas/core.yaml#
-
-title: HiSilicon SPMI controller
-
-maintainers:
- - Mauro Carvalho Chehab <mchehab+huawei@kernel.org>
-
-description: |
- The HiSilicon SPMI BUS controller is found on some Kirin-based designs.
- It is a MIPI System Power Management (SPMI) controller.
-
- The PMIC part is provided by
- drivers/staging/hikey9xx/hisilicon,hi6421-spmi-pmic.yaml.
-
-allOf:
- - $ref: spmi.yaml#
-
-properties:
-
- $nodename:
- pattern: "spmi@[0-9a-f]"
-
- compatible:
- const: hisilicon,kirin970-spmi-controller
-
- reg:
- maxItems: 1
-
- spmi-channel:
- $ref: /schemas/types.yaml#/definitions/uint32
- description: |
- number of the Kirin 970 SPMI channel where the SPMI devices are connected.
-
-required:
- - compatible
- - reg
- - spmi-channel
-
-patternProperties:
- "@[0-9a-f]$":
- description: |
- PMIC properties, which are specific to the used SPMI PMIC device(s).
- When used in combination with HiSilicon 6421v600, the properties
- are documented at
- drivers/staging/hikey9xx/hisilicon,hi6421-spmi-pmic.yaml.
-
-unevaluatedProperties: false
-
-examples:
- - |
- bus {
- #address-cells = <2>;
- #size-cells = <2>;
-
- spmi: spmi@fff24000 {
- compatible = "hisilicon,kirin970-spmi-controller";
- #address-cells = <2>;
- #size-cells = <0>;
- reg = <0x0 0xfff24000 0x0 0x1000>;
- spmi-channel = <2>;
-
- pmic@0 {
- reg = <0 0>;
- /* pmic properties */
- };
- };
- };
diff --git a/drivers/staging/hikey9xx/phy-hi3670-usb3.c b/drivers/staging/hikey9xx/phy-hi3670-usb3.c
deleted file mode 100644
index e7e579ce0302..000000000000
--- a/drivers/staging/hikey9xx/phy-hi3670-usb3.c
+++ /dev/null
@@ -1,668 +0,0 @@
-// SPDX-License-Identifier: GPL-2.0-only
-/*
- * Phy provider for USB 3.1 controller on HiSilicon Kirin970 platform
- *
- * Copyright (C) 2017-2020 Hilisicon Electronics Co., Ltd.
- * http://www.huawei.com
- *
- * Authors: Yu Chen <chenyu56@huawei.com>
- */
-
-#include <linux/bitfield.h>
-#include <linux/clk.h>
-#include <linux/kernel.h>
-#include <linux/mfd/syscon.h>
-#include <linux/module.h>
-#include <linux/phy/phy.h>
-#include <linux/platform_device.h>
-#include <linux/regmap.h>
-
-#define SCTRL_SCDEEPSLEEPED (0x0)
-#define USB_CLK_SELECTED BIT(20)
-
-#define PERI_CRG_PEREN0 (0x00)
-#define PERI_CRG_PERDIS0 (0x04)
-#define PERI_CRG_PEREN4 (0x40)
-#define PERI_CRG_PERDIS4 (0x44)
-#define PERI_CRG_PERRSTEN4 (0x90)
-#define PERI_CRG_PERRSTDIS4 (0x94)
-#define PERI_CRG_ISODIS (0x148)
-#define PERI_CRG_PEREN6 (0x410)
-#define PERI_CRG_PERDIS6 (0x414)
-
-#define USB_REFCLK_ISO_EN BIT(25)
-
-#define GT_CLK_USB2PHY_REF BIT(19)
-
-#define PCTRL_PERI_CTRL3 (0x10)
-#define PCTRL_PERI_CTRL3_MSK_START (16)
-#define USB_TCXO_EN BIT(1)
-
-#define PCTRL_PERI_CTRL24 (0x64)
-#define SC_CLK_USB3PHY_3MUX1_SEL BIT(25)
-
-#define USB3OTG_CTRL0 (0x00)
-#define USB3OTG_CTRL3 (0x0c)
-#define USB3OTG_CTRL4 (0x10)
-#define USB3OTG_CTRL5 (0x14)
-#define USB3OTG_CTRL7 (0x1c)
-#define USB_MISC_CFG50 (0x50)
-#define USB_MISC_CFG54 (0x54)
-#define USB_MISC_CFG58 (0x58)
-#define USB_MISC_CFG5C (0x5c)
-#define USB_MISC_CFGA0 (0xa0)
-#define TCA_CLK_RST (0x200)
-#define TCA_INTR_EN (0x204)
-#define TCA_INTR_STS (0x208)
-#define TCA_GCFG (0x210)
-#define TCA_TCPC (0x214)
-#define TCA_SYSMODE_CFG (0x218)
-#define TCA_VBUS_CTRL (0x240)
-
-#define CTRL0_USB3_VBUSVLD BIT(7)
-#define CTRL0_USB3_VBUSVLD_SEL BIT(6)
-
-#define CTRL3_USB2_VBUSVLDEXT0 BIT(6)
-#define CTRL3_USB2_VBUSVLDEXTSEL0 BIT(5)
-
-#define CTRL5_USB2_SIDDQ BIT(0)
-
-#define CTRL7_USB2_REFCLKSEL_MASK GENMASK(4, 3)
-#define CTRL7_USB2_REFCLKSEL_ABB (BIT(4) | BIT(3))
-#define CTRL7_USB2_REFCLKSEL_PAD BIT(4)
-
-#define CFG50_USB3_PHY_TEST_POWERDOWN BIT(23)
-
-#define CFG54_USB31PHY_CR_ADDR_MASK GENMASK(31, 16)
-
-#define CFG54_USB3PHY_REF_USE_PAD BIT(12)
-#define CFG54_PHY0_PMA_PWR_STABLE BIT(11)
-#define CFG54_PHY0_PCS_PWR_STABLE BIT(9)
-#define CFG54_USB31PHY_CR_ACK BIT(7)
-#define CFG54_USB31PHY_CR_WR_EN BIT(5)
-#define CFG54_USB31PHY_CR_SEL BIT(4)
-#define CFG54_USB31PHY_CR_RD_EN BIT(3)
-#define CFG54_USB31PHY_CR_CLK BIT(2)
-#define CFG54_USB3_PHY0_ANA_PWR_EN BIT(1)
-
-#define CFG58_USB31PHY_CR_DATA_MASK GENMASK(31, 16)
-
-#define CFG5C_USB3_PHY0_SS_MPLLA_SSC_EN BIT(1)
-
-#define CFGA0_VAUX_RESET BIT(9)
-#define CFGA0_USB31C_RESET BIT(8)
-#define CFGA0_USB2PHY_REFCLK_SELECT BIT(4)
-#define CFGA0_USB3PHY_RESET BIT(1)
-#define CFGA0_USB2PHY_POR BIT(0)
-
-#define INTR_EN_XA_TIMEOUT_EVT_EN BIT(1)
-#define INTR_EN_XA_ACK_EVT_EN BIT(0)
-
-#define CLK_RST_TCA_REF_CLK_EN BIT(1)
-#define CLK_RST_SUSPEND_CLK_EN BIT(0)
-
-#define GCFG_ROLE_HSTDEV BIT(4)
-#define GCFG_OP_MODE GENMASK(1, 0)
-#define GCFG_OP_MODE_CTRL_SYNC_MODE BIT(0)
-
-#define TCPC_VALID BIT(4)
-#define TCPC_LOW_POWER_EN BIT(3)
-#define TCPC_MUX_CONTROL_MASK GENMASK(1, 0)
-#define TCPC_MUX_CONTROL_USB31 BIT(0)
-
-#define SYSMODE_CFG_TYPEC_DISABLE BIT(3)
-
-#define VBUS_CTRL_POWERPRESENT_OVERRD GENMASK(3, 2)
-#define VBUS_CTRL_VBUSVALID_OVERRD GENMASK(1, 0)
-
-#define KIRIN970_USB_DEFAULT_PHY_PARAM (0xfdfee4)
-#define KIRIN970_USB_DEFAULT_PHY_VBOOST (0x5)
-
-#define TX_VBOOST_LVL_REG (0xf)
-#define TX_VBOOST_LVL_START (6)
-#define TX_VBOOST_LVL_ENABLE BIT(9)
-
-struct hi3670_priv {
- struct device *dev;
- struct regmap *peri_crg;
- struct regmap *pctrl;
- struct regmap *sctrl;
- struct regmap *usb31misc;
-
- u32 eye_diagram_param;
- u32 tx_vboost_lvl;
-
- u32 peri_crg_offset;
- u32 pctrl_offset;
- u32 usb31misc_offset;
-};
-
-static int hi3670_phy_cr_clk(struct regmap *usb31misc)
-{
- int ret;
-
- /* Clock up */
- ret = regmap_update_bits(usb31misc, USB_MISC_CFG54,
- CFG54_USB31PHY_CR_CLK, CFG54_USB31PHY_CR_CLK);
- if (ret)
- return ret;
-
- /* Clock down */
- ret = regmap_update_bits(usb31misc, USB_MISC_CFG54,
- CFG54_USB31PHY_CR_CLK, 0);
-
- return ret;
-}
-
-static int hi3670_phy_cr_set_sel(struct regmap *usb31misc)
-{
- return regmap_update_bits(usb31misc, USB_MISC_CFG54,
- CFG54_USB31PHY_CR_SEL, CFG54_USB31PHY_CR_SEL);
-}
-
-static int hi3670_phy_cr_start(struct regmap *usb31misc, int direction)
-{
- int ret, reg;
-
- if (direction)
- reg = CFG54_USB31PHY_CR_WR_EN;
- else
- reg = CFG54_USB31PHY_CR_RD_EN;
-
- ret = regmap_update_bits(usb31misc, USB_MISC_CFG54, reg, reg);
-
- if (ret)
- return ret;
-
- ret = hi3670_phy_cr_clk(usb31misc);
- if (ret)
- return ret;
-
- return regmap_update_bits(usb31misc, USB_MISC_CFG54,
- CFG54_USB31PHY_CR_RD_EN | CFG54_USB31PHY_CR_WR_EN, 0);
-}
-
-static int hi3670_phy_cr_wait_ack(struct regmap *usb31misc)
-{
- u32 reg;
- int retry = 10;
- int ret;
-
- while (retry-- > 0) {
- ret = regmap_read(usb31misc, USB_MISC_CFG54, &reg);
- if (ret)
- return ret;
- if ((reg & CFG54_USB31PHY_CR_ACK) == CFG54_USB31PHY_CR_ACK)
- return 0;
-
- ret = hi3670_phy_cr_clk(usb31misc);
- if (ret)
- return ret;
-
- usleep_range(10, 20);
- }
-
- return -ETIMEDOUT;
-}
-
-static int hi3670_phy_cr_set_addr(struct regmap *usb31misc, u32 addr)
-{
- u32 reg;
- int ret;
-
- ret = regmap_read(usb31misc, USB_MISC_CFG54, &reg);
- if (ret)
- return ret;
-
- reg = FIELD_PREP(CFG54_USB31PHY_CR_ADDR_MASK, addr);
- ret = regmap_update_bits(usb31misc, USB_MISC_CFG54,
- CFG54_USB31PHY_CR_ADDR_MASK, reg);
-
- return ret;
-}
-
-static int hi3670_phy_cr_read(struct regmap *usb31misc, u32 addr, u32 *val)
-{
- int reg;
- int i;
- int ret;
-
- for (i = 0; i < 100; i++) {
- ret = hi3670_phy_cr_clk(usb31misc);
- if (ret)
- return ret;
- }
-
- ret = hi3670_phy_cr_set_sel(usb31misc);
- if (ret)
- return ret;
-
- ret = hi3670_phy_cr_set_addr(usb31misc, addr);
- if (ret)
- return ret;
-
- ret = hi3670_phy_cr_start(usb31misc, 0);
- if (ret)
- return ret;
-
- ret = hi3670_phy_cr_wait_ack(usb31misc);
- if (ret)
- return ret;
-
- ret = regmap_read(usb31misc, USB_MISC_CFG58, &reg);
- if (ret)
- return ret;
-
- *val = FIELD_GET(CFG58_USB31PHY_CR_DATA_MASK, reg);
-
- return 0;
-}
-
-static int hi3670_phy_cr_write(struct regmap *usb31misc, u32 addr, u32 val)
-{
- int i;
- int ret;
-
- for (i = 0; i < 100; i++) {
- ret = hi3670_phy_cr_clk(usb31misc);
- if (ret)
- return ret;
- }
-
- ret = hi3670_phy_cr_set_sel(usb31misc);
- if (ret)
- return ret;
-
- ret = hi3670_phy_cr_set_addr(usb31misc, addr);
- if (ret)
- return ret;
-
- ret = regmap_write(usb31misc, USB_MISC_CFG58,
- FIELD_PREP(CFG58_USB31PHY_CR_DATA_MASK, val));
- if (ret)
- return ret;
-
- ret = hi3670_phy_cr_start(usb31misc, 1);
- if (ret)
- return ret;
-
- ret = hi3670_phy_cr_wait_ack(usb31misc);
-
- return ret;
-}
-
-static int hi3670_phy_set_params(struct hi3670_priv *priv)
-{
- u32 reg;
- int ret;
- int retry = 3;
-
- ret = regmap_write(priv->usb31misc, USB3OTG_CTRL4,
- priv->eye_diagram_param);
- if (ret) {
- dev_err(priv->dev, "set USB3OTG_CTRL4 failed\n");
- return ret;
- }
-
- while (retry-- > 0) {
- ret = hi3670_phy_cr_read(priv->usb31misc,
- TX_VBOOST_LVL_REG, &reg);
- if (!ret)
- break;
-
- if (ret != -ETIMEDOUT) {
- dev_err(priv->dev, "read TX_VBOOST_LVL_REG failed\n");
- return ret;
- }
- }
- if (ret)
- return ret;
-
- reg |= (TX_VBOOST_LVL_ENABLE | (priv->tx_vboost_lvl << TX_VBOOST_LVL_START));
- ret = hi3670_phy_cr_write(priv->usb31misc, TX_VBOOST_LVL_REG, reg);
- if (ret)
- dev_err(priv->dev, "write TX_VBOOST_LVL_REG failed\n");
-
- return ret;
-}
-
-static bool hi3670_is_abbclk_selected(struct hi3670_priv *priv)
-{
- u32 reg;
-
- if (!priv->sctrl) {
- dev_err(priv->dev, "priv->sctrl is null!\n");
- return false;
- }
-
- if (regmap_read(priv->sctrl, SCTRL_SCDEEPSLEEPED, &reg)) {
- dev_err(priv->dev, "SCTRL_SCDEEPSLEEPED read failed!\n");
- return false;
- }
-
- if ((reg & USB_CLK_SELECTED) == 0)
- return false;
-
- return true;
-}
-
-static int hi3670_config_phy_clock(struct hi3670_priv *priv)
-{
- u32 val, mask;
- int ret;
-
- if (!hi3670_is_abbclk_selected(priv)) {
- /* usb refclk iso disable */
- ret = regmap_write(priv->peri_crg, PERI_CRG_ISODIS,
- USB_REFCLK_ISO_EN);
- if (ret)
- goto out;
-
- /* enable usb_tcxo_en */
- ret = regmap_write(priv->pctrl, PCTRL_PERI_CTRL3,
- USB_TCXO_EN |
- (USB_TCXO_EN << PCTRL_PERI_CTRL3_MSK_START));
-
- /* select usbphy clk from abb */
- mask = SC_CLK_USB3PHY_3MUX1_SEL;
- ret = regmap_update_bits(priv->pctrl,
- PCTRL_PERI_CTRL24, mask, 0);
- if (ret)
- goto out;
-
- ret = regmap_update_bits(priv->usb31misc, USB_MISC_CFGA0,
- CFGA0_USB2PHY_REFCLK_SELECT, 0);
- if (ret)
- goto out;
-
- ret = regmap_read(priv->usb31misc, USB3OTG_CTRL7, &val);
- if (ret)
- goto out;
- val &= ~CTRL7_USB2_REFCLKSEL_MASK;
- val |= CTRL7_USB2_REFCLKSEL_ABB;
- ret = regmap_write(priv->usb31misc, USB3OTG_CTRL7, val);
- if (ret)
- goto out;
-
- return 0;
- }
-
- ret = regmap_update_bits(priv->usb31misc, USB_MISC_CFG54,
- CFG54_USB3PHY_REF_USE_PAD,
- CFG54_USB3PHY_REF_USE_PAD);
- if (ret)
- goto out;
-
- ret = regmap_update_bits(priv->usb31misc, USB_MISC_CFGA0,
- CFGA0_USB2PHY_REFCLK_SELECT,
- CFGA0_USB2PHY_REFCLK_SELECT);
- if (ret)
- goto out;
-
- ret = regmap_read(priv->usb31misc, USB3OTG_CTRL7, &val);
- if (ret)
- goto out;
- val &= ~CTRL7_USB2_REFCLKSEL_MASK;
- val |= CTRL7_USB2_REFCLKSEL_PAD;
- ret = regmap_write(priv->usb31misc, USB3OTG_CTRL7, val);
- if (ret)
- goto out;
-
- ret = regmap_write(priv->peri_crg,
- PERI_CRG_PEREN6, GT_CLK_USB2PHY_REF);
- if (ret)
- goto out;
-
- return 0;
-out:
- dev_err(priv->dev, "failed to config phy clock ret: %d\n", ret);
- return ret;
-}
-
-static int hi3670_config_tca(struct hi3670_priv *priv)
-{
- u32 val, mask;
- int ret;
-
- ret = regmap_write(priv->usb31misc, TCA_INTR_STS, 0xffff);
- if (ret)
- goto out;
-
- ret = regmap_write(priv->usb31misc, TCA_INTR_EN,
- INTR_EN_XA_TIMEOUT_EVT_EN | INTR_EN_XA_ACK_EVT_EN);
- if (ret)
- goto out;
-
- mask = CLK_RST_TCA_REF_CLK_EN | CLK_RST_SUSPEND_CLK_EN;
- ret = regmap_update_bits(priv->usb31misc, TCA_CLK_RST, mask, 0);
- if (ret)
- goto out;
-
- ret = regmap_update_bits(priv->usb31misc, TCA_GCFG,
- GCFG_ROLE_HSTDEV | GCFG_OP_MODE,
- GCFG_ROLE_HSTDEV | GCFG_OP_MODE_CTRL_SYNC_MODE);
- if (ret)
- goto out;
-
- ret = regmap_update_bits(priv->usb31misc, TCA_SYSMODE_CFG,
- SYSMODE_CFG_TYPEC_DISABLE, 0);
- if (ret)
- goto out;
-
- ret = regmap_read(priv->usb31misc, TCA_TCPC, &val);
- if (ret)
- goto out;
- val &= ~(TCPC_VALID | TCPC_LOW_POWER_EN | TCPC_MUX_CONTROL_MASK);
- val |= (TCPC_VALID | TCPC_MUX_CONTROL_USB31);
- ret = regmap_write(priv->usb31misc, TCA_TCPC, val);
- if (ret)
- goto out;
-
- ret = regmap_write(priv->usb31misc, TCA_VBUS_CTRL,
- VBUS_CTRL_POWERPRESENT_OVERRD | VBUS_CTRL_VBUSVALID_OVERRD);
- if (ret)
- goto out;
-
- return 0;
-out:
- dev_err(priv->dev, "failed to config phy clock ret: %d\n", ret);
- return ret;
-}
-
-static int hi3670_phy_init(struct phy *phy)
-{
- struct hi3670_priv *priv = phy_get_drvdata(phy);
- u32 val;
- int ret;
-
- /* assert controller */
- val = CFGA0_VAUX_RESET | CFGA0_USB31C_RESET |
- CFGA0_USB3PHY_RESET | CFGA0_USB2PHY_POR;
- ret = regmap_update_bits(priv->usb31misc, USB_MISC_CFGA0, val, 0);
- if (ret)
- goto out;
-
- ret = hi3670_config_phy_clock(priv);
- if (ret)
- goto out;
-
- /* Exit from IDDQ mode */
- ret = regmap_update_bits(priv->usb31misc, USB3OTG_CTRL5,
- CTRL5_USB2_SIDDQ, 0);
- if (ret)
- goto out;
-
- /* Release USB31 PHY out of TestPowerDown mode */
- ret = regmap_update_bits(priv->usb31misc, USB_MISC_CFG50,
- CFG50_USB3_PHY_TEST_POWERDOWN, 0);
- if (ret)
- goto out;
-
- /* Deassert phy */
- val = CFGA0_USB3PHY_RESET | CFGA0_USB2PHY_POR;
- ret = regmap_update_bits(priv->usb31misc, USB_MISC_CFGA0, val, val);
- if (ret)
- goto out;
-
- usleep_range(100, 120);
-
- /* Tell the PHY power is stable */
- val = CFG54_USB3_PHY0_ANA_PWR_EN | CFG54_PHY0_PCS_PWR_STABLE |
- CFG54_PHY0_PMA_PWR_STABLE;
- ret = regmap_update_bits(priv->usb31misc, USB_MISC_CFG54,
- val, val);
- if (ret)
- goto out;
-
- ret = hi3670_config_tca(priv);
- if (ret)
- goto out;
-
- /* Enable SSC */
- ret = regmap_update_bits(priv->usb31misc, USB_MISC_CFG5C,
- CFG5C_USB3_PHY0_SS_MPLLA_SSC_EN,
- CFG5C_USB3_PHY0_SS_MPLLA_SSC_EN);
- if (ret)
- goto out;
-
- /* Deassert controller */
- val = CFGA0_VAUX_RESET | CFGA0_USB31C_RESET;
- ret = regmap_update_bits(priv->usb31misc, USB_MISC_CFGA0, val, val);
- if (ret)
- goto out;
-
- usleep_range(100, 120);
-
- /* Set fake vbus valid signal */
- val = CTRL0_USB3_VBUSVLD | CTRL0_USB3_VBUSVLD_SEL;
- ret = regmap_update_bits(priv->usb31misc, USB3OTG_CTRL0, val, val);
- if (ret)
- goto out;
-
- val = CTRL3_USB2_VBUSVLDEXT0 | CTRL3_USB2_VBUSVLDEXTSEL0;
- ret = regmap_update_bits(priv->usb31misc, USB3OTG_CTRL3, val, val);
- if (ret)
- goto out;
-
- usleep_range(100, 120);
-
- ret = hi3670_phy_set_params(priv);
- if (ret)
- goto out;
-
- return 0;
-out:
- dev_err(priv->dev, "failed to init phy ret: %d\n", ret);
- return ret;
-}
-
-static int hi3670_phy_exit(struct phy *phy)
-{
- struct hi3670_priv *priv = phy_get_drvdata(phy);
- u32 mask;
- int ret;
-
- /* Assert phy */
- mask = CFGA0_USB3PHY_RESET | CFGA0_USB2PHY_POR;
- ret = regmap_update_bits(priv->usb31misc, USB_MISC_CFGA0, mask, 0);
- if (ret)
- goto out;
-
- if (!hi3670_is_abbclk_selected(priv)) {
- /* disable usb_tcxo_en */
- ret = regmap_write(priv->pctrl, PCTRL_PERI_CTRL3,
- USB_TCXO_EN << PCTRL_PERI_CTRL3_MSK_START);
- } else {
- ret = regmap_write(priv->peri_crg, PERI_CRG_PERDIS6,
- GT_CLK_USB2PHY_REF);
- if (ret)
- goto out;
- }
-
- return 0;
-out:
- dev_err(priv->dev, "failed to exit phy ret: %d\n", ret);
- return ret;
-}
-
-static const struct phy_ops hi3670_phy_ops = {
- .init = hi3670_phy_init,
- .exit = hi3670_phy_exit,
- .owner = THIS_MODULE,
-};
-
-static int hi3670_phy_probe(struct platform_device *pdev)
-{
- struct phy_provider *phy_provider;
- struct device *dev = &pdev->dev;
- struct phy *phy;
- struct hi3670_priv *priv;
-
- priv = devm_kzalloc(dev, sizeof(*priv), GFP_KERNEL);
- if (!priv)
- return -ENOMEM;
-
- priv->dev = dev;
- priv->peri_crg = syscon_regmap_lookup_by_phandle(dev->of_node,
- "hisilicon,pericrg-syscon");
- if (IS_ERR(priv->peri_crg)) {
- dev_err(dev, "no hisilicon,pericrg-syscon\n");
- return PTR_ERR(priv->peri_crg);
- }
-
- priv->pctrl = syscon_regmap_lookup_by_phandle(dev->of_node,
- "hisilicon,pctrl-syscon");
- if (IS_ERR(priv->pctrl)) {
- dev_err(dev, "no hisilicon,pctrl-syscon\n");
- return PTR_ERR(priv->pctrl);
- }
-
- priv->sctrl = syscon_regmap_lookup_by_phandle(dev->of_node,
- "hisilicon,sctrl-syscon");
- if (IS_ERR(priv->sctrl)) {
- dev_err(dev, "no hisilicon,sctrl-syscon\n");
- return PTR_ERR(priv->sctrl);
- }
-
- /* node of hi3670 phy is a sub-node of usb3_otg_bc */
- priv->usb31misc = syscon_node_to_regmap(dev->parent->of_node);
- if (IS_ERR(priv->usb31misc)) {
- dev_err(dev, "no hisilicon,usb3-otg-bc-syscon\n");
- return PTR_ERR(priv->usb31misc);
- }
-
- if (of_property_read_u32(dev->of_node, "hisilicon,eye-diagram-param",
- &priv->eye_diagram_param))
- priv->eye_diagram_param = KIRIN970_USB_DEFAULT_PHY_PARAM;
-
- if (of_property_read_u32(dev->of_node, "hisilicon,tx-vboost-lvl",
- &priv->tx_vboost_lvl))
- priv->tx_vboost_lvl = KIRIN970_USB_DEFAULT_PHY_VBOOST;
-
- phy = devm_phy_create(dev, NULL, &hi3670_phy_ops);
- if (IS_ERR(phy))
- return PTR_ERR(phy);
-
- phy_set_drvdata(phy, priv);
- phy_provider = devm_of_phy_provider_register(dev, of_phy_simple_xlate);
- return PTR_ERR_OR_ZERO(phy_provider);
-}
-
-static const struct of_device_id hi3670_phy_of_match[] = {
- { .compatible = "hisilicon,hi3670-usb-phy" },
- { },
-};
-MODULE_DEVICE_TABLE(of, hi3670_phy_of_match);
-
-static struct platform_driver hi3670_phy_driver = {
- .probe = hi3670_phy_probe,
- .driver = {
- .name = "hi3670-usb-phy",
- .of_match_table = hi3670_phy_of_match,
- }
-};
-module_platform_driver(hi3670_phy_driver);
-
-MODULE_AUTHOR("Yu Chen <chenyu56@huawei.com>");
-MODULE_LICENSE("GPL v2");
-MODULE_DESCRIPTION("Hilisicon Kirin970 USB31 PHY Driver");
diff --git a/drivers/staging/hikey9xx/phy-hi3670-usb3.yaml b/drivers/staging/hikey9xx/phy-hi3670-usb3.yaml
deleted file mode 100644
index ebd78acfe2de..000000000000
--- a/drivers/staging/hikey9xx/phy-hi3670-usb3.yaml
+++ /dev/null
@@ -1,73 +0,0 @@
-# SPDX-License-Identifier: GPL-2.0
-%YAML 1.2
----
-$id: http://devicetree.org/schemas/phy/hisilicon,hi3670-usb3.yaml#
-$schema: http://devicetree.org/meta-schemas/core.yaml#
-
-title: Hisilicon Kirin970 USB PHY
-
-maintainers:
- - Mauro Carvalho Chehab <mchehab+huawei@kernel.org>
-
-description: |+
- Bindings for USB3 PHY on HiSilicon Kirin 970.
-
-properties:
- compatible:
- const: hisilicon,hi3670-usb-phy
-
- "#phy-cells":
- const: 0
-
- hisilicon,pericrg-syscon:
- $ref: '/schemas/types.yaml#/definitions/phandle'
- description: phandle of syscon used to control iso refclk.
-
- hisilicon,pctrl-syscon:
- $ref: '/schemas/types.yaml#/definitions/phandle'
- description: phandle of syscon used to control usb tcxo.
-
- hisilicon,sctrl-syscon:
- $ref: '/schemas/types.yaml#/definitions/phandle'
- description: phandle of syscon used to control phy deep sleep.
-
- hisilicon,eye-diagram-param:
- $ref: /schemas/types.yaml#/definitions/uint32
- description: Eye diagram for phy.
-
- hisilicon,tx-vboost-lvl:
- $ref: /schemas/types.yaml#/definitions/uint32
- description: TX level vboost for phy.
-
-required:
- - compatible
- - hisilicon,pericrg-syscon
- - hisilicon,pctrl-syscon
- - hisilicon,sctrl-syscon
- - hisilicon,eye-diagram-param
- - hisilicon,tx-vboost-lvl
- - "#phy-cells"
-
-additionalProperties: false
-
-examples:
- - |
- bus {
- #address-cells = <2>;
- #size-cells = <2>;
-
- usb3_otg_bc: usb3_otg_bc@ff200000 {
- compatible = "syscon", "simple-mfd";
- reg = <0x0 0xff200000 0x0 0x1000>;
-
- usb_phy {
- compatible = "hisilicon,hi3670-usb-phy";
- #phy-cells = <0>;
- hisilicon,pericrg-syscon = <&crg_ctrl>;
- hisilicon,pctrl-syscon = <&pctrl>;
- hisilicon,sctrl-syscon = <&sctrl>;
- hisilicon,eye-diagram-param = <0xfdfee4>;
- hisilicon,tx-vboost-lvl = <0x5>;
- };
- };
- };