mirror of
https://github.com/AuxXxilium/linux_dsm_epyc7002.git
synced 2024-12-28 11:18:45 +07:00
DaVinci SoC support improvements mainly towards an effort to
get to working USB support. - use CFGCHIP syscon device to access common registers - define platform data and device tree nodes for newly introduced USB phy driver - clock lookup and auxdata lookup for USB phy and also for LCDC (LCD controller) -----BEGIN PGP SIGNATURE----- Version: GnuPG v1 iQIcBAABAgAGBQJYHCFWAAoJEGFBu2jqvgRNsiMP/AtyFsKue1Y+hNm5EXUwnHVF kmJn1AfXzYa2xn9fPQIIrraqQxNobbl5BiEuLgFk33s6C0wrAz3/5FjnsguoJ+UD 7BNzMpXHac4nLORRMTdKlACGv7rsrRelSrKZr6dAd0puEnKqRlSORBJTcGRCLJPh pqTJM5X53NsGlhJOXnk33CDxuK4Ym/nVtbvKBzi2nGBbWiIWIvn/jzwZqkNCYzdc iDQzIDMfeP9G8l8JkL7A947Yolf2h7hYqPDKRFhJSSvvdGUNEkbHyu4iSG7qE+B4 z/aLvvH6sB3CPeKqum1PMAk8hEV+Mp3lsTtrdFLgxz4NsY1jcIriSIDBY+x5Fkfh jKOsmkniwysVHsWvta4pLJMwnamfg/SG05wCCTb/PDO4S3NFnB4L9rdslzo7A0ad M6ewqKUFOCMsSyxyGBEiSA1UuWblkzeKOh8dcx1Q/haYPMfJUzzeRMeaXNLpUR+l fAqoKQBTAA5szydu83qKJLUDugkYZxaoeIw7wIo2JhqCaubyoGUZ6rpyaDiA+M0K kC6KIDmSunensISvTRxHPrjkPcalLY6x6VJNDnMTMrf4CfwYCqLlA2LlqG770xjK Th46PAjHr6SyPbjHwLxm3EZC385eKtTTlc7wdSHF/iR9Bt/EMnIynJgqKGc0YXDC yNMITMhPxl09K5eR1JO4 =tA0U -----END PGP SIGNATURE----- Merge tag 'davinci-for-v4.10/soc' of git://git.kernel.org/pub/scm/linux/kernel/git/nsekhar/linux-davinci into next/soc DaVinci SoC support improvements mainly towards an effort to get to working USB support. - use CFGCHIP syscon device to access common registers - define platform data and device tree nodes for newly introduced USB phy driver - clock lookup and auxdata lookup for USB phy and also for LCDC (LCD controller) * tag 'davinci-for-v4.10/soc' of git://git.kernel.org/pub/scm/linux/kernel/git/nsekhar/linux-davinci: ARM: davinci: da8xx: register USB PHY clocks in the DT file ARM: davinci: da8xx: add usb phy clocks ARM: davinci: da8xx-dt: add OF_DEV_AUXDATA entry for USB phy ARM: davinci: da8xx: Add USB device names to clock lookup tables ARM: davinci: da8xx: Add USB PHY platform device ARM: davinci: da8xx-dt: add OF_DEV_AUXDATA entry for lcdc ARM: davinci: da8xx: Add full regulator constraints for non-DT boot ARM: davinci: da8xx: Add CFGCHIP syscon platform device Signed-off-by: Olof Johansson <olof@lixom.net>
This commit is contained in:
commit
1474f44ec8
@ -18,7 +18,6 @@
|
||||
#include <linux/i2c.h>
|
||||
#include <linux/i2c/pcf857x.h>
|
||||
#include <linux/platform_data/at24.h>
|
||||
#include <linux/mfd/da8xx-cfgchip.h>
|
||||
#include <linux/mtd/mtd.h>
|
||||
#include <linux/mtd/partitions.h>
|
||||
#include <linux/spi/spi.h>
|
||||
@ -28,6 +27,7 @@
|
||||
#include <linux/platform_data/mtd-davinci-aemif.h>
|
||||
#include <linux/platform_data/spi-davinci.h>
|
||||
#include <linux/platform_data/usb-davinci.h>
|
||||
#include <linux/regulator/machine.h>
|
||||
|
||||
#include <asm/mach-types.h>
|
||||
#include <asm/mach/arch.h>
|
||||
@ -107,43 +107,24 @@ static irqreturn_t da830_evm_usb_ocic_irq(int irq, void *dev_id)
|
||||
|
||||
static __init void da830_evm_usb_init(void)
|
||||
{
|
||||
u32 cfgchip2;
|
||||
int ret;
|
||||
|
||||
/*
|
||||
* Set up USB clock/mode in the CFGCHIP2 register.
|
||||
* FYI: CFGCHIP2 is 0x0000ef00 initially.
|
||||
*/
|
||||
cfgchip2 = __raw_readl(DA8XX_SYSCFG0_VIRT(DA8XX_CFGCHIP2_REG));
|
||||
|
||||
/* USB2.0 PHY reference clock is 24 MHz */
|
||||
cfgchip2 &= ~CFGCHIP2_REFFREQ_MASK;
|
||||
cfgchip2 |= CFGCHIP2_REFFREQ_24MHZ;
|
||||
|
||||
/*
|
||||
* Select internal reference clock for USB 2.0 PHY
|
||||
* and use it as a clock source for USB 1.1 PHY
|
||||
* (this is the default setting anyway).
|
||||
*/
|
||||
cfgchip2 &= ~CFGCHIP2_USB1PHYCLKMUX;
|
||||
cfgchip2 |= CFGCHIP2_USB2PHYCLKMUX;
|
||||
|
||||
/*
|
||||
* We have to override VBUS/ID signals when MUSB is configured into the
|
||||
* host-only mode -- ID pin will float if no cable is connected, so the
|
||||
* controller won't be able to drive VBUS thinking that it's a B-device.
|
||||
* Otherwise, we want to use the OTG mode and enable VBUS comparators.
|
||||
*/
|
||||
cfgchip2 &= ~CFGCHIP2_OTGMODE_MASK;
|
||||
#ifdef CONFIG_USB_MUSB_HOST
|
||||
cfgchip2 |= CFGCHIP2_FORCE_HOST;
|
||||
#else
|
||||
cfgchip2 |= CFGCHIP2_SESENDEN | CFGCHIP2_VBDTCTEN;
|
||||
#endif
|
||||
|
||||
__raw_writel(cfgchip2, DA8XX_SYSCFG0_VIRT(DA8XX_CFGCHIP2_REG));
|
||||
|
||||
/* USB_REFCLKIN is not used. */
|
||||
ret = da8xx_register_usb20_phy_clk(false);
|
||||
if (ret)
|
||||
pr_warn("%s: USB 2.0 PHY CLK registration failed: %d\n",
|
||||
__func__, ret);
|
||||
|
||||
ret = da8xx_register_usb11_phy_clk(false);
|
||||
if (ret)
|
||||
pr_warn("%s: USB 1.1 PHY CLK registration failed: %d\n",
|
||||
__func__, ret);
|
||||
|
||||
ret = da8xx_register_usb_phy();
|
||||
if (ret)
|
||||
pr_warn("%s: USB PHY registration failed: %d\n",
|
||||
__func__, ret);
|
||||
|
||||
ret = davinci_cfg_reg(DA830_USB0_DRVVBUS);
|
||||
if (ret)
|
||||
pr_warn("%s: USB 2.0 PinMux setup failed: %d\n", __func__, ret);
|
||||
@ -589,6 +570,10 @@ static __init void da830_evm_init(void)
|
||||
struct davinci_soc_info *soc_info = &davinci_soc_info;
|
||||
int ret;
|
||||
|
||||
ret = da8xx_register_cfgchip();
|
||||
if (ret)
|
||||
pr_warn("%s: CFGCHIP registration failed: %d\n", __func__, ret);
|
||||
|
||||
ret = da830_register_gpio();
|
||||
if (ret)
|
||||
pr_warn("%s: GPIO init failed: %d\n", __func__, ret);
|
||||
@ -648,6 +633,8 @@ static __init void da830_evm_init(void)
|
||||
ret = da8xx_register_spi_bus(0, ARRAY_SIZE(da830evm_spi_info));
|
||||
if (ret)
|
||||
pr_warn("%s: spi 0 registration failed: %d\n", __func__, ret);
|
||||
|
||||
regulator_has_full_constraints();
|
||||
}
|
||||
|
||||
#ifdef CONFIG_SERIAL_8250_CONSOLE
|
||||
|
@ -1345,6 +1345,10 @@ static __init void da850_evm_init(void)
|
||||
{
|
||||
int ret;
|
||||
|
||||
ret = da8xx_register_cfgchip();
|
||||
if (ret)
|
||||
pr_warn("%s: CFGCHIP registration failed: %d\n", __func__, ret);
|
||||
|
||||
ret = da850_register_gpio();
|
||||
if (ret)
|
||||
pr_warn("%s: GPIO init failed: %d\n", __func__, ret);
|
||||
|
@ -514,6 +514,10 @@ static void __init mityomapl138_init(void)
|
||||
{
|
||||
int ret;
|
||||
|
||||
ret = da8xx_register_cfgchip();
|
||||
if (ret)
|
||||
pr_warn("%s: CFGCHIP registration failed: %d\n", __func__, ret);
|
||||
|
||||
/* for now, no special EDMA channels are reserved */
|
||||
ret = da850_register_edma(NULL);
|
||||
if (ret)
|
||||
|
@ -13,8 +13,8 @@
|
||||
#include <linux/init.h>
|
||||
#include <linux/console.h>
|
||||
#include <linux/gpio.h>
|
||||
#include <linux/mfd/da8xx-cfgchip.h>
|
||||
#include <linux/platform_data/gpio-davinci.h>
|
||||
#include <linux/regulator/machine.h>
|
||||
|
||||
#include <asm/mach-types.h>
|
||||
#include <asm/mach/arch.h>
|
||||
@ -244,7 +244,6 @@ static irqreturn_t omapl138_hawk_usb_ocic_irq(int irq, void *dev_id)
|
||||
static __init void omapl138_hawk_usb_init(void)
|
||||
{
|
||||
int ret;
|
||||
u32 cfgchip2;
|
||||
|
||||
ret = davinci_cfg_reg_list(da850_hawk_usb11_pins);
|
||||
if (ret) {
|
||||
@ -252,12 +251,20 @@ static __init void omapl138_hawk_usb_init(void)
|
||||
return;
|
||||
}
|
||||
|
||||
/* Setup the Ref. clock frequency for the HAWK at 24 MHz. */
|
||||
ret = da8xx_register_usb20_phy_clk(false);
|
||||
if (ret)
|
||||
pr_warn("%s: USB 2.0 PHY CLK registration failed: %d\n",
|
||||
__func__, ret);
|
||||
|
||||
cfgchip2 = __raw_readl(DA8XX_SYSCFG0_VIRT(DA8XX_CFGCHIP2_REG));
|
||||
cfgchip2 &= ~CFGCHIP2_REFFREQ_MASK;
|
||||
cfgchip2 |= CFGCHIP2_REFFREQ_24MHZ;
|
||||
__raw_writel(cfgchip2, DA8XX_SYSCFG0_VIRT(DA8XX_CFGCHIP2_REG));
|
||||
ret = da8xx_register_usb11_phy_clk(false);
|
||||
if (ret)
|
||||
pr_warn("%s: USB 1.1 PHY CLK registration failed: %d\n",
|
||||
__func__, ret);
|
||||
|
||||
ret = da8xx_register_usb_phy();
|
||||
if (ret)
|
||||
pr_warn("%s: USB PHY registration failed: %d\n",
|
||||
__func__, ret);
|
||||
|
||||
ret = gpio_request_one(DA850_USB1_VBUS_PIN,
|
||||
GPIOF_DIR_OUT, "USB1 VBUS");
|
||||
@ -293,6 +300,10 @@ static __init void omapl138_hawk_init(void)
|
||||
{
|
||||
int ret;
|
||||
|
||||
ret = da8xx_register_cfgchip();
|
||||
if (ret)
|
||||
pr_warn("%s: CFGCHIP registration failed: %d\n", __func__, ret);
|
||||
|
||||
ret = da850_register_gpio();
|
||||
if (ret)
|
||||
pr_warn("%s: GPIO init failed: %d\n", __func__, ret);
|
||||
@ -318,6 +329,8 @@ static __init void omapl138_hawk_init(void)
|
||||
if (ret)
|
||||
pr_warn("%s: dsp/rproc registration failed: %d\n",
|
||||
__func__, ret);
|
||||
|
||||
regulator_has_full_constraints();
|
||||
}
|
||||
|
||||
#ifdef CONFIG_SERIAL_8250_CONSOLE
|
||||
|
@ -412,7 +412,7 @@ static struct clk_lookup da830_clks[] = {
|
||||
CLK("davinci-mcasp.0", NULL, &mcasp0_clk),
|
||||
CLK("davinci-mcasp.1", NULL, &mcasp1_clk),
|
||||
CLK("davinci-mcasp.2", NULL, &mcasp2_clk),
|
||||
CLK(NULL, "usb20", &usb20_clk),
|
||||
CLK("musb-da8xx", "usb20", &usb20_clk),
|
||||
CLK(NULL, "aemif", &aemif_clk),
|
||||
CLK(NULL, "aintc", &aintc_clk),
|
||||
CLK(NULL, "secu_mgr", &secu_mgr_clk),
|
||||
@ -420,7 +420,7 @@ static struct clk_lookup da830_clks[] = {
|
||||
CLK("davinci_mdio.0", "fck", &emac_clk),
|
||||
CLK(NULL, "gpio", &gpio_clk),
|
||||
CLK("i2c_davinci.2", NULL, &i2c1_clk),
|
||||
CLK(NULL, "usb11", &usb11_clk),
|
||||
CLK("ohci", "usb11", &usb11_clk),
|
||||
CLK(NULL, "emif3", &emif3_clk),
|
||||
CLK(NULL, "arm", &arm_clk),
|
||||
CLK(NULL, "rmii", &rmii_clk),
|
||||
|
@ -503,8 +503,8 @@ static struct clk_lookup da850_clks[] = {
|
||||
CLK("da830-mmc.1", NULL, &mmcsd1_clk),
|
||||
CLK("ti-aemif", NULL, &aemif_clk),
|
||||
CLK(NULL, "aemif", &aemif_clk),
|
||||
CLK(NULL, "usb11", &usb11_clk),
|
||||
CLK(NULL, "usb20", &usb20_clk),
|
||||
CLK("ohci", "usb11", &usb11_clk),
|
||||
CLK("musb-da8xx", "usb20", &usb20_clk),
|
||||
CLK("spi_davinci.0", NULL, &spi0_clk),
|
||||
CLK("spi_davinci.1", NULL, &spi1_clk),
|
||||
CLK("vpif", NULL, &vpif_clk),
|
||||
|
@ -38,6 +38,10 @@ static struct of_dev_auxdata da850_auxdata_lookup[] __initdata = {
|
||||
NULL),
|
||||
OF_DEV_AUXDATA("ti,da830-mcasp-audio", 0x01d00000, "davinci-mcasp.0", NULL),
|
||||
OF_DEV_AUXDATA("ti,da850-aemif", 0x68000000, "ti-aemif", NULL),
|
||||
OF_DEV_AUXDATA("ti,da850-tilcdc", 0x01e13000, "da8xx_lcdc.0", NULL),
|
||||
OF_DEV_AUXDATA("ti,da830-ohci", 0x01e25000, "ohci", NULL),
|
||||
OF_DEV_AUXDATA("ti,da830-musb", 0x01e00000, "musb-da8xx", NULL),
|
||||
OF_DEV_AUXDATA("ti,da830-usb-phy", 0x01c1417c, "da8xx-usb-phy", NULL),
|
||||
{}
|
||||
};
|
||||
|
||||
@ -45,6 +49,17 @@ static struct of_dev_auxdata da850_auxdata_lookup[] __initdata = {
|
||||
|
||||
static void __init da850_init_machine(void)
|
||||
{
|
||||
int ret;
|
||||
|
||||
ret = da8xx_register_usb20_phy_clk(false);
|
||||
if (ret)
|
||||
pr_warn("%s: registering USB 2.0 PHY clock failed: %d",
|
||||
__func__, ret);
|
||||
ret = da8xx_register_usb11_phy_clk(false);
|
||||
if (ret)
|
||||
pr_warn("%s: registering USB 1.1 PHY clock failed: %d",
|
||||
__func__, ret);
|
||||
|
||||
of_platform_default_populate(NULL, da850_auxdata_lookup, NULL);
|
||||
}
|
||||
|
||||
|
@ -11,6 +11,7 @@
|
||||
* (at your option) any later version.
|
||||
*/
|
||||
#include <linux/init.h>
|
||||
#include <linux/platform_data/syscon.h>
|
||||
#include <linux/platform_device.h>
|
||||
#include <linux/dma-contiguous.h>
|
||||
#include <linux/serial_8250.h>
|
||||
@ -1060,3 +1061,30 @@ int __init da850_register_sata(unsigned long refclkpn)
|
||||
return platform_device_register(&da850_sata_device);
|
||||
}
|
||||
#endif
|
||||
|
||||
static struct syscon_platform_data da8xx_cfgchip_platform_data = {
|
||||
.label = "cfgchip",
|
||||
};
|
||||
|
||||
static struct resource da8xx_cfgchip_resources[] = {
|
||||
{
|
||||
.start = DA8XX_SYSCFG0_BASE + DA8XX_CFGCHIP0_REG,
|
||||
.end = DA8XX_SYSCFG0_BASE + DA8XX_CFGCHIP4_REG + 3,
|
||||
.flags = IORESOURCE_MEM,
|
||||
},
|
||||
};
|
||||
|
||||
static struct platform_device da8xx_cfgchip_device = {
|
||||
.name = "syscon",
|
||||
.id = -1,
|
||||
.dev = {
|
||||
.platform_data = &da8xx_cfgchip_platform_data,
|
||||
},
|
||||
.num_resources = ARRAY_SIZE(da8xx_cfgchip_resources),
|
||||
.resource = da8xx_cfgchip_resources,
|
||||
};
|
||||
|
||||
int __init da8xx_register_cfgchip(void)
|
||||
{
|
||||
return platform_device_register(&da8xx_cfgchip_device);
|
||||
}
|
||||
|
@ -61,6 +61,7 @@ extern unsigned int da850_max_speed;
|
||||
#define DA8XX_CFGCHIP1_REG 0x180
|
||||
#define DA8XX_CFGCHIP2_REG 0x184
|
||||
#define DA8XX_CFGCHIP3_REG 0x188
|
||||
#define DA8XX_CFGCHIP4_REG 0x18c
|
||||
|
||||
#define DA8XX_SYSCFG1_BASE (IO_PHYS + 0x22C000)
|
||||
#define DA8XX_SYSCFG1_VIRT(x) (da8xx_syscfg1_base + (x))
|
||||
@ -88,8 +89,12 @@ int da850_register_edma(struct edma_rsv_info *rsv[2]);
|
||||
int da8xx_register_i2c(int instance, struct davinci_i2c_platform_data *pdata);
|
||||
int da8xx_register_spi_bus(int instance, unsigned num_chipselect);
|
||||
int da8xx_register_watchdog(void);
|
||||
int da8xx_register_usb_phy(void);
|
||||
int da8xx_register_usb20(unsigned mA, unsigned potpgt);
|
||||
int da8xx_register_usb11(struct da8xx_ohci_root_hub *pdata);
|
||||
int da8xx_register_usb_refclkin(int rate);
|
||||
int da8xx_register_usb20_phy_clk(bool use_usb_refclkin);
|
||||
int da8xx_register_usb11_phy_clk(bool use_usb_refclkin);
|
||||
int da8xx_register_emac(void);
|
||||
int da8xx_register_uio_pruss(void);
|
||||
int da8xx_register_lcdc(struct da8xx_lcdc_platform_data *pdata);
|
||||
@ -113,6 +118,7 @@ void da8xx_rproc_reserve_cma(void);
|
||||
int da8xx_register_rproc(void);
|
||||
int da850_register_gpio(void);
|
||||
int da830_register_gpio(void);
|
||||
int da8xx_register_cfgchip(void);
|
||||
|
||||
extern struct platform_device da8xx_serial_device[];
|
||||
extern struct emac_platform_data da8xx_emac_pdata;
|
||||
|
@ -1,21 +1,44 @@
|
||||
/*
|
||||
* DA8xx USB
|
||||
*/
|
||||
#include <linux/clk.h>
|
||||
#include <linux/delay.h>
|
||||
#include <linux/dma-mapping.h>
|
||||
#include <linux/init.h>
|
||||
#include <linux/mfd/da8xx-cfgchip.h>
|
||||
#include <linux/phy/phy.h>
|
||||
#include <linux/platform_data/usb-davinci.h>
|
||||
#include <linux/platform_device.h>
|
||||
#include <linux/usb/musb.h>
|
||||
|
||||
#include <mach/clock.h>
|
||||
#include <mach/common.h>
|
||||
#include <mach/cputype.h>
|
||||
#include <mach/da8xx.h>
|
||||
#include <mach/irqs.h>
|
||||
|
||||
#include "clock.h"
|
||||
|
||||
#define DA8XX_USB0_BASE 0x01e00000
|
||||
#define DA8XX_USB1_BASE 0x01e25000
|
||||
|
||||
#if IS_ENABLED(CONFIG_USB_MUSB_HDRC)
|
||||
static struct platform_device da8xx_usb_phy = {
|
||||
.name = "da8xx-usb-phy",
|
||||
.id = -1,
|
||||
.dev = {
|
||||
/*
|
||||
* Setting init_name so that clock lookup will work in
|
||||
* da8xx_register_usb11_phy_clk() even if this device is not
|
||||
* registered yet.
|
||||
*/
|
||||
.init_name = "da8xx-usb-phy",
|
||||
},
|
||||
};
|
||||
|
||||
int __init da8xx_register_usb_phy(void)
|
||||
{
|
||||
return platform_device_register(&da8xx_usb_phy);
|
||||
}
|
||||
|
||||
static struct musb_hdrc_config musb_config = {
|
||||
.multipoint = true,
|
||||
@ -45,10 +68,15 @@ static struct resource da8xx_usb20_resources[] = {
|
||||
|
||||
static u64 usb_dmamask = DMA_BIT_MASK(32);
|
||||
|
||||
static struct platform_device usb_dev = {
|
||||
static struct platform_device da8xx_usb20_dev = {
|
||||
.name = "musb-da8xx",
|
||||
.id = -1,
|
||||
.dev = {
|
||||
/*
|
||||
* Setting init_name so that clock lookup will work in
|
||||
* usb20_phy_clk_enable() even if this device is not registered.
|
||||
*/
|
||||
.init_name = "musb-da8xx",
|
||||
.platform_data = &usb_data,
|
||||
.dma_mask = &usb_dmamask,
|
||||
.coherent_dma_mask = DMA_BIT_MASK(32),
|
||||
@ -62,18 +90,9 @@ int __init da8xx_register_usb20(unsigned int mA, unsigned int potpgt)
|
||||
usb_data.power = mA > 510 ? 255 : mA / 2;
|
||||
usb_data.potpgt = (potpgt + 1) / 2;
|
||||
|
||||
return platform_device_register(&usb_dev);
|
||||
return platform_device_register(&da8xx_usb20_dev);
|
||||
}
|
||||
|
||||
#else
|
||||
|
||||
int __init da8xx_register_usb20(unsigned int mA, unsigned int potpgt)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
#endif /* CONFIG_USB_MUSB_HDRC */
|
||||
|
||||
static struct resource da8xx_usb11_resources[] = {
|
||||
[0] = {
|
||||
.start = DA8XX_USB1_BASE,
|
||||
@ -105,3 +124,236 @@ int __init da8xx_register_usb11(struct da8xx_ohci_root_hub *pdata)
|
||||
da8xx_usb11_device.dev.platform_data = pdata;
|
||||
return platform_device_register(&da8xx_usb11_device);
|
||||
}
|
||||
|
||||
static struct clk usb_refclkin = {
|
||||
.name = "usb_refclkin",
|
||||
.set_rate = davinci_simple_set_rate,
|
||||
};
|
||||
|
||||
static struct clk_lookup usb_refclkin_lookup =
|
||||
CLK(NULL, "usb_refclkin", &usb_refclkin);
|
||||
|
||||
/**
|
||||
* da8xx_register_usb_refclkin - register USB_REFCLKIN clock
|
||||
*
|
||||
* @rate: The clock rate in Hz
|
||||
*
|
||||
* This clock is only needed if the board provides an external USB_REFCLKIN
|
||||
* signal, in which case it will be used as the parent of usb20_phy_clk and/or
|
||||
* usb11_phy_clk.
|
||||
*/
|
||||
int __init da8xx_register_usb_refclkin(int rate)
|
||||
{
|
||||
int ret;
|
||||
|
||||
usb_refclkin.rate = rate;
|
||||
ret = clk_register(&usb_refclkin);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
clkdev_add(&usb_refclkin_lookup);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void usb20_phy_clk_enable(struct clk *clk)
|
||||
{
|
||||
struct clk *usb20_clk;
|
||||
int err;
|
||||
u32 val;
|
||||
u32 timeout = 500000; /* 500 msec */
|
||||
|
||||
val = readl(DA8XX_SYSCFG0_VIRT(DA8XX_CFGCHIP2_REG));
|
||||
|
||||
usb20_clk = clk_get(&da8xx_usb20_dev.dev, "usb20");
|
||||
if (IS_ERR(usb20_clk)) {
|
||||
pr_err("could not get usb20 clk: %ld\n", PTR_ERR(usb20_clk));
|
||||
return;
|
||||
}
|
||||
|
||||
/* The USB 2.O PLL requires that the USB 2.O PSC is enabled as well. */
|
||||
err = clk_prepare_enable(usb20_clk);
|
||||
if (err) {
|
||||
pr_err("failed to enable usb20 clk: %d\n", err);
|
||||
clk_put(usb20_clk);
|
||||
return;
|
||||
}
|
||||
|
||||
/*
|
||||
* Turn on the USB 2.0 PHY, but just the PLL, and not OTG. The USB 1.1
|
||||
* host may use the PLL clock without USB 2.0 OTG being used.
|
||||
*/
|
||||
val &= ~(CFGCHIP2_RESET | CFGCHIP2_PHYPWRDN);
|
||||
val |= CFGCHIP2_PHY_PLLON;
|
||||
|
||||
writel(val, DA8XX_SYSCFG0_VIRT(DA8XX_CFGCHIP2_REG));
|
||||
|
||||
while (--timeout) {
|
||||
val = readl(DA8XX_SYSCFG0_VIRT(DA8XX_CFGCHIP2_REG));
|
||||
if (val & CFGCHIP2_PHYCLKGD)
|
||||
goto done;
|
||||
udelay(1);
|
||||
}
|
||||
|
||||
pr_err("Timeout waiting for USB 2.0 PHY clock good\n");
|
||||
done:
|
||||
clk_disable_unprepare(usb20_clk);
|
||||
clk_put(usb20_clk);
|
||||
}
|
||||
|
||||
static void usb20_phy_clk_disable(struct clk *clk)
|
||||
{
|
||||
u32 val;
|
||||
|
||||
val = readl(DA8XX_SYSCFG0_VIRT(DA8XX_CFGCHIP2_REG));
|
||||
val |= CFGCHIP2_PHYPWRDN;
|
||||
writel(val, DA8XX_SYSCFG0_VIRT(DA8XX_CFGCHIP2_REG));
|
||||
}
|
||||
|
||||
static int usb20_phy_clk_set_parent(struct clk *clk, struct clk *parent)
|
||||
{
|
||||
u32 val;
|
||||
|
||||
val = readl(DA8XX_SYSCFG0_VIRT(DA8XX_CFGCHIP2_REG));
|
||||
|
||||
/* Set the mux depending on the parent clock. */
|
||||
if (parent == &usb_refclkin) {
|
||||
val &= ~CFGCHIP2_USB2PHYCLKMUX;
|
||||
} else if (strcmp(parent->name, "pll0_aux_clk") == 0) {
|
||||
val |= CFGCHIP2_USB2PHYCLKMUX;
|
||||
} else {
|
||||
pr_err("Bad parent on USB 2.0 PHY clock\n");
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
/* reference frequency also comes from parent clock */
|
||||
val &= ~CFGCHIP2_REFFREQ_MASK;
|
||||
switch (clk_get_rate(parent)) {
|
||||
case 12000000:
|
||||
val |= CFGCHIP2_REFFREQ_12MHZ;
|
||||
break;
|
||||
case 13000000:
|
||||
val |= CFGCHIP2_REFFREQ_13MHZ;
|
||||
break;
|
||||
case 19200000:
|
||||
val |= CFGCHIP2_REFFREQ_19_2MHZ;
|
||||
break;
|
||||
case 20000000:
|
||||
val |= CFGCHIP2_REFFREQ_20MHZ;
|
||||
break;
|
||||
case 24000000:
|
||||
val |= CFGCHIP2_REFFREQ_24MHZ;
|
||||
break;
|
||||
case 26000000:
|
||||
val |= CFGCHIP2_REFFREQ_26MHZ;
|
||||
break;
|
||||
case 38400000:
|
||||
val |= CFGCHIP2_REFFREQ_38_4MHZ;
|
||||
break;
|
||||
case 40000000:
|
||||
val |= CFGCHIP2_REFFREQ_40MHZ;
|
||||
break;
|
||||
case 48000000:
|
||||
val |= CFGCHIP2_REFFREQ_48MHZ;
|
||||
break;
|
||||
default:
|
||||
pr_err("Bad parent clock rate on USB 2.0 PHY clock\n");
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
writel(val, DA8XX_SYSCFG0_VIRT(DA8XX_CFGCHIP2_REG));
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static struct clk usb20_phy_clk = {
|
||||
.name = "usb20_phy",
|
||||
.clk_enable = usb20_phy_clk_enable,
|
||||
.clk_disable = usb20_phy_clk_disable,
|
||||
.set_parent = usb20_phy_clk_set_parent,
|
||||
};
|
||||
|
||||
static struct clk_lookup usb20_phy_clk_lookup =
|
||||
CLK("da8xx-usb-phy", "usb20_phy", &usb20_phy_clk);
|
||||
|
||||
/**
|
||||
* da8xx_register_usb20_phy_clk - register USB0PHYCLKMUX clock
|
||||
*
|
||||
* @use_usb_refclkin: Selects the parent clock - either "usb_refclkin" if true
|
||||
* or "pll0_aux" if false.
|
||||
*/
|
||||
int __init da8xx_register_usb20_phy_clk(bool use_usb_refclkin)
|
||||
{
|
||||
struct clk *parent;
|
||||
int ret = 0;
|
||||
|
||||
parent = clk_get(NULL, use_usb_refclkin ? "usb_refclkin" : "pll0_aux");
|
||||
if (IS_ERR(parent))
|
||||
return PTR_ERR(parent);
|
||||
|
||||
usb20_phy_clk.parent = parent;
|
||||
ret = clk_register(&usb20_phy_clk);
|
||||
if (!ret)
|
||||
clkdev_add(&usb20_phy_clk_lookup);
|
||||
|
||||
clk_put(parent);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int usb11_phy_clk_set_parent(struct clk *clk, struct clk *parent)
|
||||
{
|
||||
u32 val;
|
||||
|
||||
val = readl(DA8XX_SYSCFG0_VIRT(DA8XX_CFGCHIP2_REG));
|
||||
|
||||
/* Set the USB 1.1 PHY clock mux based on the parent clock. */
|
||||
if (parent == &usb20_phy_clk) {
|
||||
val &= ~CFGCHIP2_USB1PHYCLKMUX;
|
||||
} else if (parent == &usb_refclkin) {
|
||||
val |= CFGCHIP2_USB1PHYCLKMUX;
|
||||
} else {
|
||||
pr_err("Bad parent on USB 1.1 PHY clock\n");
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
writel(val, DA8XX_SYSCFG0_VIRT(DA8XX_CFGCHIP2_REG));
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static struct clk usb11_phy_clk = {
|
||||
.name = "usb11_phy",
|
||||
.set_parent = usb11_phy_clk_set_parent,
|
||||
};
|
||||
|
||||
static struct clk_lookup usb11_phy_clk_lookup =
|
||||
CLK("da8xx-usb-phy", "usb11_phy", &usb11_phy_clk);
|
||||
|
||||
/**
|
||||
* da8xx_register_usb11_phy_clk - register USB1PHYCLKMUX clock
|
||||
*
|
||||
* @use_usb_refclkin: Selects the parent clock - either "usb_refclkin" if true
|
||||
* or "usb20_phy" if false.
|
||||
*/
|
||||
int __init da8xx_register_usb11_phy_clk(bool use_usb_refclkin)
|
||||
{
|
||||
struct clk *parent;
|
||||
int ret = 0;
|
||||
|
||||
if (use_usb_refclkin)
|
||||
parent = clk_get(NULL, "usb_refclkin");
|
||||
else
|
||||
parent = clk_get(&da8xx_usb_phy.dev, "usb20_phy");
|
||||
if (IS_ERR(parent))
|
||||
return PTR_ERR(parent);
|
||||
|
||||
usb11_phy_clk.parent = parent;
|
||||
ret = clk_register(&usb11_phy_clk);
|
||||
if (!ret)
|
||||
clkdev_add(&usb11_phy_clk_lookup);
|
||||
|
||||
clk_put(parent);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user