/* * Intel Sunrisepoint LPSS core support. * * Copyright (C) 2015, Intel Corporation * * Authors: Andy Shevchenko * Mika Westerberg * Heikki Krogerus * Jarkko Nikula * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 2 as * published by the Free Software Foundation. */ #include #include #include #include #include #include #include #include #include #include #include #include #include #include "intel-lpss.h" #define LPSS_DEV_OFFSET 0x000 #define LPSS_DEV_SIZE 0x200 #define LPSS_PRIV_OFFSET 0x200 #define LPSS_PRIV_SIZE 0x100 #define LPSS_PRIV_REG_COUNT (LPSS_PRIV_SIZE / 4) #define LPSS_IDMA64_OFFSET 0x800 #define LPSS_IDMA64_SIZE 0x800 /* Offsets from lpss->priv */ #define LPSS_PRIV_RESETS 0x04 #define LPSS_PRIV_RESETS_FUNC BIT(2) #define LPSS_PRIV_RESETS_IDMA 0x3 #define LPSS_PRIV_ACTIVELTR 0x10 #define LPSS_PRIV_IDLELTR 0x14 #define LPSS_PRIV_LTR_REQ BIT(15) #define LPSS_PRIV_LTR_SCALE_MASK 0xc00 #define LPSS_PRIV_LTR_SCALE_1US 0x800 #define LPSS_PRIV_LTR_SCALE_32US 0xc00 #define LPSS_PRIV_LTR_VALUE_MASK 0x3ff #define LPSS_PRIV_SSP_REG 0x20 #define LPSS_PRIV_SSP_REG_DIS_DMA_FIN BIT(0) #define LPSS_PRIV_REMAP_ADDR 0x40 #define LPSS_PRIV_CAPS 0xfc #define LPSS_PRIV_CAPS_NO_IDMA BIT(8) #define LPSS_PRIV_CAPS_TYPE_SHIFT 4 #define LPSS_PRIV_CAPS_TYPE_MASK (0xf << LPSS_PRIV_CAPS_TYPE_SHIFT) /* This matches the type field in CAPS register */ enum intel_lpss_dev_type { LPSS_DEV_I2C = 0, LPSS_DEV_UART, LPSS_DEV_SPI, }; struct intel_lpss { const struct intel_lpss_platform_info *info; enum intel_lpss_dev_type type; struct clk *clk; struct clk_lookup *clock; const struct mfd_cell *cell; struct device *dev; void __iomem *priv; u32 priv_ctx[LPSS_PRIV_REG_COUNT]; int devid; u32 caps; u32 active_ltr; u32 idle_ltr; struct dentry *debugfs; }; static const struct resource intel_lpss_dev_resources[] = { DEFINE_RES_MEM_NAMED(LPSS_DEV_OFFSET, LPSS_DEV_SIZE, "lpss_dev"), DEFINE_RES_MEM_NAMED(LPSS_PRIV_OFFSET, LPSS_PRIV_SIZE, "lpss_priv"), DEFINE_RES_IRQ(0), }; static const struct resource intel_lpss_idma64_resources[] = { DEFINE_RES_MEM(LPSS_IDMA64_OFFSET, LPSS_IDMA64_SIZE), DEFINE_RES_IRQ(0), }; #define LPSS_IDMA64_DRIVER_NAME "idma64" /* * Cells needs to be ordered so that the iDMA is created first. This is * because we need to be sure the DMA is available when the host controller * driver is probed. */ static const struct mfd_cell intel_lpss_idma64_cell = { .name = LPSS_IDMA64_DRIVER_NAME, .num_resources = ARRAY_SIZE(intel_lpss_idma64_resources), .resources = intel_lpss_idma64_resources, }; static const struct mfd_cell intel_lpss_i2c_cell = { .name = "i2c_designware", .num_resources = ARRAY_SIZE(intel_lpss_dev_resources), .resources = intel_lpss_dev_resources, }; static const struct mfd_cell intel_lpss_uart_cell = { .name = "dw-apb-uart", .num_resources = ARRAY_SIZE(intel_lpss_dev_resources), .resources = intel_lpss_dev_resources, }; static const struct mfd_cell intel_lpss_spi_cell = { .name = "pxa2xx-spi", .num_resources = ARRAY_SIZE(intel_lpss_dev_resources), .resources = intel_lpss_dev_resources, }; static DEFINE_IDA(intel_lpss_devid_ida); static struct dentry *intel_lpss_debugfs; static int intel_lps