Orange Pi5 kernel

Deprecated Linux kernel 5.10.110 for OrangePi 5/5B/5+ boards

3 Commits   0 Branches   0 Tags
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   1) // SPDX-License-Identifier: GPL-2.0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   2) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   3)  * Copyright (c) 2016 Linaro Ltd.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   4)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   5) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   6) #include <linux/device.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   7) #include <linux/usb/chipidea.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   8) #include <linux/ulpi/interface.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   9) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  10) #include "ci.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  11) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  12) #define ULPI_WAKEUP		BIT(31)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  13) #define ULPI_RUN		BIT(30)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  14) #define ULPI_WRITE		BIT(29)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  15) #define ULPI_SYNC_STATE		BIT(27)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  16) #define ULPI_ADDR(n)		((n) << 16)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  17) #define ULPI_DATA(n)		(n)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  18) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  19) static int ci_ulpi_wait(struct ci_hdrc *ci, u32 mask)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  20) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  21) 	unsigned long usec = 10000;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  22) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  23) 	while (usec--) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  24) 		if (!hw_read(ci, OP_ULPI_VIEWPORT, mask))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  25) 			return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  26) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  27) 		udelay(1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  28) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  29) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  30) 	return -ETIMEDOUT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  31) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  32) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  33) static int ci_ulpi_read(struct device *dev, u8 addr)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  34) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  35) 	struct ci_hdrc *ci = dev_get_drvdata(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  36) 	int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  37) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  38) 	hw_write(ci, OP_ULPI_VIEWPORT, 0xffffffff, ULPI_WRITE | ULPI_WAKEUP);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  39) 	ret = ci_ulpi_wait(ci, ULPI_WAKEUP);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  40) 	if (ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  41) 		return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  42) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  43) 	hw_write(ci, OP_ULPI_VIEWPORT, 0xffffffff, ULPI_RUN | ULPI_ADDR(addr));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  44) 	ret = ci_ulpi_wait(ci, ULPI_RUN);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  45) 	if (ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  46) 		return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  47) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  48) 	return hw_read(ci, OP_ULPI_VIEWPORT, GENMASK(15, 8)) >> 8;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  49) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  50) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  51) static int ci_ulpi_write(struct device *dev, u8 addr, u8 val)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  52) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  53) 	struct ci_hdrc *ci = dev_get_drvdata(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  54) 	int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  55) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  56) 	hw_write(ci, OP_ULPI_VIEWPORT, 0xffffffff, ULPI_WRITE | ULPI_WAKEUP);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  57) 	ret = ci_ulpi_wait(ci, ULPI_WAKEUP);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  58) 	if (ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  59) 		return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  60) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  61) 	hw_write(ci, OP_ULPI_VIEWPORT, 0xffffffff,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  62) 		 ULPI_RUN | ULPI_WRITE | ULPI_ADDR(addr) | val);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  63) 	return ci_ulpi_wait(ci, ULPI_RUN);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  64) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  65) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  66) int ci_ulpi_init(struct ci_hdrc *ci)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  67) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  68) 	if (ci->platdata->phy_mode != USBPHY_INTERFACE_MODE_ULPI)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  69) 		return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  70) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  71) 	/*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  72) 	 * Set PORTSC correctly so we can read/write ULPI registers for
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  73) 	 * identification purposes
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  74) 	 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  75) 	hw_phymode_configure(ci);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  76) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  77) 	ci->ulpi_ops.read = ci_ulpi_read;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  78) 	ci->ulpi_ops.write = ci_ulpi_write;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  79) 	ci->ulpi = ulpi_register_interface(ci->dev, &ci->ulpi_ops);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  80) 	if (IS_ERR(ci->ulpi))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  81) 		dev_err(ci->dev, "failed to register ULPI interface");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  82) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  83) 	return PTR_ERR_OR_ZERO(ci->ulpi);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  84) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  85) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  86) void ci_ulpi_exit(struct ci_hdrc *ci)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  87) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  88) 	if (ci->ulpi) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  89) 		ulpi_unregister_interface(ci->ulpi);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  90) 		ci->ulpi = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  91) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  92) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  93) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  94) int ci_ulpi_resume(struct ci_hdrc *ci)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  95) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  96) 	int cnt = 100000;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  97) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  98) 	if (ci->platdata->phy_mode != USBPHY_INTERFACE_MODE_ULPI)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  99) 		return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 100) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 101) 	while (cnt-- > 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 102) 		if (hw_read(ci, OP_ULPI_VIEWPORT, ULPI_SYNC_STATE))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 103) 			return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 104) 		udelay(1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 105) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 106) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 107) 	return -ETIMEDOUT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 108) }