cachepc-linux

Fork of AMDESE/linux with modifications for CachePC side-channel attack
git clone https://git.sinitax.com/sinitax/cachepc-linux
Log | Files | Refs | README | LICENSE | sfeed.txt

pxa2xx-ac97-lib.c (11223B)


      1// SPDX-License-Identifier: GPL-2.0-only
      2/*
      3 * Based on sound/arm/pxa2xx-ac97.c and sound/soc/pxa/pxa2xx-ac97.c
      4 * which contain:
      5 *
      6 * Author:	Nicolas Pitre
      7 * Created:	Dec 02, 2004
      8 * Copyright:	MontaVista Software Inc.
      9 */
     10
     11#include <linux/kernel.h>
     12#include <linux/platform_device.h>
     13#include <linux/interrupt.h>
     14#include <linux/clk.h>
     15#include <linux/delay.h>
     16#include <linux/module.h>
     17#include <linux/io.h>
     18#include <linux/gpio.h>
     19#include <linux/of_gpio.h>
     20#include <linux/soc/pxa/cpu.h>
     21
     22#include <sound/pxa2xx-lib.h>
     23
     24#include <linux/platform_data/asoc-pxa.h>
     25
     26#include "pxa2xx-ac97-regs.h"
     27
     28static DEFINE_MUTEX(car_mutex);
     29static DECLARE_WAIT_QUEUE_HEAD(gsr_wq);
     30static volatile long gsr_bits;
     31static struct clk *ac97_clk;
     32static struct clk *ac97conf_clk;
     33static int reset_gpio;
     34static void __iomem *ac97_reg_base;
     35
     36extern void pxa27x_configure_ac97reset(int reset_gpio, bool to_gpio);
     37
     38/*
     39 * Beware PXA27x bugs:
     40 *
     41 *   o Slot 12 read from modem space will hang controller.
     42 *   o CDONE, SDONE interrupt fails after any slot 12 IO.
     43 *
     44 * We therefore have an hybrid approach for waiting on SDONE (interrupt or
     45 * 1 jiffy timeout if interrupt never comes).
     46 */
     47
     48int pxa2xx_ac97_read(int slot, unsigned short reg)
     49{
     50	int val = -ENODEV;
     51	u32 __iomem *reg_addr;
     52
     53	if (slot > 0)
     54		return -ENODEV;
     55
     56	mutex_lock(&car_mutex);
     57
     58	/* set up primary or secondary codec space */
     59	if (cpu_is_pxa25x() && reg == AC97_GPIO_STATUS)
     60		reg_addr = ac97_reg_base +
     61			   (slot ? SMC_REG_BASE : PMC_REG_BASE);
     62	else
     63		reg_addr = ac97_reg_base +
     64			   (slot ? SAC_REG_BASE : PAC_REG_BASE);
     65	reg_addr += (reg >> 1);
     66
     67	/* start read access across the ac97 link */
     68	writel(GSR_CDONE | GSR_SDONE, ac97_reg_base + GSR);
     69	gsr_bits = 0;
     70	val = (readl(reg_addr) & 0xffff);
     71	if (reg == AC97_GPIO_STATUS)
     72		goto out;
     73	if (wait_event_timeout(gsr_wq, (readl(ac97_reg_base + GSR) | gsr_bits) & GSR_SDONE, 1) <= 0 &&
     74	    !((readl(ac97_reg_base + GSR) | gsr_bits) & GSR_SDONE)) {
     75		printk(KERN_ERR "%s: read error (ac97_reg=%d GSR=%#lx)\n",
     76				__func__, reg, readl(ac97_reg_base + GSR) | gsr_bits);
     77		val = -ETIMEDOUT;
     78		goto out;
     79	}
     80
     81	/* valid data now */
     82	writel(GSR_CDONE | GSR_SDONE, ac97_reg_base + GSR);
     83	gsr_bits = 0;
     84	val = (readl(reg_addr) & 0xffff);
     85	/* but we've just started another cycle... */
     86	wait_event_timeout(gsr_wq, (readl(ac97_reg_base + GSR) | gsr_bits) & GSR_SDONE, 1);
     87
     88out:	mutex_unlock(&car_mutex);
     89	return val;
     90}
     91EXPORT_SYMBOL_GPL(pxa2xx_ac97_read);
     92
     93int pxa2xx_ac97_write(int slot, unsigned short reg, unsigned short val)
     94{
     95	u32 __iomem *reg_addr;
     96	int ret = 0;
     97
     98	mutex_lock(&car_mutex);
     99
    100	/* set up primary or secondary codec space */
    101	if (cpu_is_pxa25x() && reg == AC97_GPIO_STATUS)
    102		reg_addr = ac97_reg_base +
    103			   (slot ? SMC_REG_BASE : PMC_REG_BASE);
    104	else
    105		reg_addr = ac97_reg_base +
    106			   (slot ? SAC_REG_BASE : PAC_REG_BASE);
    107	reg_addr += (reg >> 1);
    108
    109	writel(GSR_CDONE | GSR_SDONE, ac97_reg_base + GSR);
    110	gsr_bits = 0;
    111	writel(val, reg_addr);
    112	if (wait_event_timeout(gsr_wq, (readl(ac97_reg_base + GSR) | gsr_bits) & GSR_CDONE, 1) <= 0 &&
    113	    !((readl(ac97_reg_base + GSR) | gsr_bits) & GSR_CDONE)) {
    114		printk(KERN_ERR "%s: write error (ac97_reg=%d GSR=%#lx)\n",
    115				__func__, reg, readl(ac97_reg_base + GSR) | gsr_bits);
    116		ret = -EIO;
    117	}
    118
    119	mutex_unlock(&car_mutex);
    120	return ret;
    121}
    122EXPORT_SYMBOL_GPL(pxa2xx_ac97_write);
    123
    124#ifdef CONFIG_PXA25x
    125static inline void pxa_ac97_warm_pxa25x(void)
    126{
    127	gsr_bits = 0;
    128
    129	writel(readl(ac97_reg_base + GCR) | (GCR_WARM_RST), ac97_reg_base + GCR);
    130}
    131
    132static inline void pxa_ac97_cold_pxa25x(void)
    133{
    134	writel(readl(ac97_reg_base + GCR) & ( GCR_COLD_RST), ac97_reg_base + GCR);  /* clear everything but nCRST */
    135	writel(readl(ac97_reg_base + GCR) & (~GCR_COLD_RST), ac97_reg_base + GCR);  /* then assert nCRST */
    136
    137	gsr_bits = 0;
    138
    139	writel(GCR_COLD_RST, ac97_reg_base + GCR);
    140}
    141#endif
    142
    143#ifdef CONFIG_PXA27x
    144static inline void pxa_ac97_warm_pxa27x(void)
    145{
    146	gsr_bits = 0;
    147
    148	/* warm reset broken on Bulverde, so manually keep AC97 reset high */
    149	pxa27x_configure_ac97reset(reset_gpio, true);
    150	udelay(10);
    151	writel(readl(ac97_reg_base + GCR) | (GCR_WARM_RST), ac97_reg_base + GCR);
    152	pxa27x_configure_ac97reset(reset_gpio, false);
    153	udelay(500);
    154}
    155
    156static inline void pxa_ac97_cold_pxa27x(void)
    157{
    158	writel(readl(ac97_reg_base + GCR) & ( GCR_COLD_RST), ac97_reg_base + GCR);  /* clear everything but nCRST */
    159	writel(readl(ac97_reg_base + GCR) & (~GCR_COLD_RST), ac97_reg_base + GCR);  /* then assert nCRST */
    160
    161	gsr_bits = 0;
    162
    163	/* PXA27x Developers Manual section 13.5.2.2.1 */
    164	clk_prepare_enable(ac97conf_clk);
    165	udelay(5);
    166	clk_disable_unprepare(ac97conf_clk);
    167	writel(GCR_COLD_RST | GCR_WARM_RST, ac97_reg_base + GCR);
    168}
    169#endif
    170
    171#ifdef CONFIG_PXA3xx
    172static inline void pxa_ac97_warm_pxa3xx(void)
    173{
    174	gsr_bits = 0;
    175
    176	/* Can't use interrupts */
    177	writel(readl(ac97_reg_base + GCR) | (GCR_WARM_RST), ac97_reg_base + GCR);
    178}
    179
    180static inline void pxa_ac97_cold_pxa3xx(void)
    181{
    182	/* Hold CLKBPB for 100us */
    183	writel(0, ac97_reg_base + GCR);
    184	writel(GCR_CLKBPB, ac97_reg_base + GCR);
    185	udelay(100);
    186	writel(0, ac97_reg_base + GCR);
    187
    188	writel(readl(ac97_reg_base + GCR) & ( GCR_COLD_RST), ac97_reg_base + GCR);  /* clear everything but nCRST */
    189	writel(readl(ac97_reg_base + GCR) & (~GCR_COLD_RST), ac97_reg_base + GCR);  /* then assert nCRST */
    190
    191	gsr_bits = 0;
    192
    193	/* Can't use interrupts on PXA3xx */
    194	writel(readl(ac97_reg_base + GCR) & (~(GCR_PRIRDY_IEN|GCR_SECRDY_IEN)), ac97_reg_base + GCR);
    195
    196	writel(GCR_WARM_RST | GCR_COLD_RST, ac97_reg_base + GCR);
    197}
    198#endif
    199
    200bool pxa2xx_ac97_try_warm_reset(void)
    201{
    202	unsigned long gsr;
    203	unsigned int timeout = 100;
    204
    205#ifdef CONFIG_PXA25x
    206	if (cpu_is_pxa25x())
    207		pxa_ac97_warm_pxa25x();
    208	else
    209#endif
    210#ifdef CONFIG_PXA27x
    211	if (cpu_is_pxa27x())
    212		pxa_ac97_warm_pxa27x();
    213	else
    214#endif
    215#ifdef CONFIG_PXA3xx
    216	if (cpu_is_pxa3xx())
    217		pxa_ac97_warm_pxa3xx();
    218	else
    219#endif
    220		snd_BUG();
    221
    222	while (!((readl(ac97_reg_base + GSR) | gsr_bits) & (GSR_PCR | GSR_SCR)) && timeout--)
    223		mdelay(1);
    224
    225	gsr = readl(ac97_reg_base + GSR) | gsr_bits;
    226	if (!(gsr & (GSR_PCR | GSR_SCR))) {
    227		printk(KERN_INFO "%s: warm reset timeout (GSR=%#lx)\n",
    228				 __func__, gsr);
    229
    230		return false;
    231	}
    232
    233	return true;
    234}
    235EXPORT_SYMBOL_GPL(pxa2xx_ac97_try_warm_reset);
    236
    237bool pxa2xx_ac97_try_cold_reset(void)
    238{
    239	unsigned long gsr;
    240	unsigned int timeout = 1000;
    241
    242#ifdef CONFIG_PXA25x
    243	if (cpu_is_pxa25x())
    244		pxa_ac97_cold_pxa25x();
    245	else
    246#endif
    247#ifdef CONFIG_PXA27x
    248	if (cpu_is_pxa27x())
    249		pxa_ac97_cold_pxa27x();
    250	else
    251#endif
    252#ifdef CONFIG_PXA3xx
    253	if (cpu_is_pxa3xx())
    254		pxa_ac97_cold_pxa3xx();
    255	else
    256#endif
    257		snd_BUG();
    258
    259	while (!((readl(ac97_reg_base + GSR) | gsr_bits) & (GSR_PCR | GSR_SCR)) && timeout--)
    260		mdelay(1);
    261
    262	gsr = readl(ac97_reg_base + GSR) | gsr_bits;
    263	if (!(gsr & (GSR_PCR | GSR_SCR))) {
    264		printk(KERN_INFO "%s: cold reset timeout (GSR=%#lx)\n",
    265				 __func__, gsr);
    266
    267		return false;
    268	}
    269
    270	return true;
    271}
    272EXPORT_SYMBOL_GPL(pxa2xx_ac97_try_cold_reset);
    273
    274
    275void pxa2xx_ac97_finish_reset(void)
    276{
    277	u32 gcr = readl(ac97_reg_base + GCR);
    278	gcr &= ~(GCR_PRIRDY_IEN|GCR_SECRDY_IEN);
    279	gcr |= GCR_SDONE_IE|GCR_CDONE_IE;
    280	writel(gcr, ac97_reg_base + GCR);
    281}
    282EXPORT_SYMBOL_GPL(pxa2xx_ac97_finish_reset);
    283
    284static irqreturn_t pxa2xx_ac97_irq(int irq, void *dev_id)
    285{
    286	long status;
    287
    288	status = readl(ac97_reg_base + GSR);
    289	if (status) {
    290		writel(status, ac97_reg_base + GSR);
    291		gsr_bits |= status;
    292		wake_up(&gsr_wq);
    293
    294		/* Although we don't use those we still need to clear them
    295		   since they tend to spuriously trigger when MMC is used
    296		   (hardware bug? go figure)... */
    297		if (cpu_is_pxa27x()) {
    298			writel(MISR_EOC, ac97_reg_base + MISR);
    299			writel(PISR_EOC, ac97_reg_base + PISR);
    300			writel(MCSR_EOC, ac97_reg_base + MCSR);
    301		}
    302
    303		return IRQ_HANDLED;
    304	}
    305
    306	return IRQ_NONE;
    307}
    308
    309#ifdef CONFIG_PM
    310int pxa2xx_ac97_hw_suspend(void)
    311{
    312	writel(readl(ac97_reg_base + GCR) | (GCR_ACLINK_OFF), ac97_reg_base + GCR);
    313	clk_disable_unprepare(ac97_clk);
    314	return 0;
    315}
    316EXPORT_SYMBOL_GPL(pxa2xx_ac97_hw_suspend);
    317
    318int pxa2xx_ac97_hw_resume(void)
    319{
    320	clk_prepare_enable(ac97_clk);
    321	return 0;
    322}
    323EXPORT_SYMBOL_GPL(pxa2xx_ac97_hw_resume);
    324#endif
    325
    326int pxa2xx_ac97_hw_probe(struct platform_device *dev)
    327{
    328	int ret;
    329	int irq;
    330	pxa2xx_audio_ops_t *pdata = dev->dev.platform_data;
    331
    332	ac97_reg_base = devm_platform_ioremap_resource(dev, 0);
    333	if (IS_ERR(ac97_reg_base)) {
    334		dev_err(&dev->dev, "Missing MMIO resource\n");
    335		return PTR_ERR(ac97_reg_base);
    336	}
    337
    338	if (pdata) {
    339		switch (pdata->reset_gpio) {
    340		case 95:
    341		case 113:
    342			reset_gpio = pdata->reset_gpio;
    343			break;
    344		case 0:
    345			reset_gpio = 113;
    346			break;
    347		case -1:
    348			break;
    349		default:
    350			dev_err(&dev->dev, "Invalid reset GPIO %d\n",
    351				pdata->reset_gpio);
    352		}
    353	} else if (!pdata && dev->dev.of_node) {
    354		pdata = devm_kzalloc(&dev->dev, sizeof(*pdata), GFP_KERNEL);
    355		if (!pdata)
    356			return -ENOMEM;
    357		pdata->reset_gpio = of_get_named_gpio(dev->dev.of_node,
    358						      "reset-gpios", 0);
    359		if (pdata->reset_gpio == -ENOENT)
    360			pdata->reset_gpio = -1;
    361		else if (pdata->reset_gpio < 0)
    362			return pdata->reset_gpio;
    363		reset_gpio = pdata->reset_gpio;
    364	} else {
    365		if (cpu_is_pxa27x())
    366			reset_gpio = 113;
    367	}
    368
    369	if (cpu_is_pxa27x()) {
    370		/*
    371		 * This gpio is needed for a work-around to a bug in the ac97
    372		 * controller during warm reset.  The direction and level is set
    373		 * here so that it is an output driven high when switching from
    374		 * AC97_nRESET alt function to generic gpio.
    375		 */
    376		ret = gpio_request_one(reset_gpio, GPIOF_OUT_INIT_HIGH,
    377				       "pxa27x ac97 reset");
    378		if (ret < 0) {
    379			pr_err("%s: gpio_request_one() failed: %d\n",
    380			       __func__, ret);
    381			goto err_conf;
    382		}
    383		pxa27x_configure_ac97reset(reset_gpio, false);
    384
    385		ac97conf_clk = clk_get(&dev->dev, "AC97CONFCLK");
    386		if (IS_ERR(ac97conf_clk)) {
    387			ret = PTR_ERR(ac97conf_clk);
    388			ac97conf_clk = NULL;
    389			goto err_conf;
    390		}
    391	}
    392
    393	ac97_clk = clk_get(&dev->dev, "AC97CLK");
    394	if (IS_ERR(ac97_clk)) {
    395		ret = PTR_ERR(ac97_clk);
    396		ac97_clk = NULL;
    397		goto err_clk;
    398	}
    399
    400	ret = clk_prepare_enable(ac97_clk);
    401	if (ret)
    402		goto err_clk2;
    403
    404	irq = platform_get_irq(dev, 0);
    405	if (!irq)
    406		goto err_irq;
    407
    408	ret = request_irq(irq, pxa2xx_ac97_irq, 0, "AC97", NULL);
    409	if (ret < 0)
    410		goto err_irq;
    411
    412	return 0;
    413
    414err_irq:
    415	writel(readl(ac97_reg_base + GCR) | (GCR_ACLINK_OFF), ac97_reg_base + GCR);
    416err_clk2:
    417	clk_put(ac97_clk);
    418	ac97_clk = NULL;
    419err_clk:
    420	if (ac97conf_clk) {
    421		clk_put(ac97conf_clk);
    422		ac97conf_clk = NULL;
    423	}
    424err_conf:
    425	return ret;
    426}
    427EXPORT_SYMBOL_GPL(pxa2xx_ac97_hw_probe);
    428
    429void pxa2xx_ac97_hw_remove(struct platform_device *dev)
    430{
    431	if (cpu_is_pxa27x())
    432		gpio_free(reset_gpio);
    433	writel(readl(ac97_reg_base + GCR) | (GCR_ACLINK_OFF), ac97_reg_base + GCR);
    434	free_irq(platform_get_irq(dev, 0), NULL);
    435	if (ac97conf_clk) {
    436		clk_put(ac97conf_clk);
    437		ac97conf_clk = NULL;
    438	}
    439	clk_disable_unprepare(ac97_clk);
    440	clk_put(ac97_clk);
    441	ac97_clk = NULL;
    442}
    443EXPORT_SYMBOL_GPL(pxa2xx_ac97_hw_remove);
    444
    445u32 pxa2xx_ac97_read_modr(void)
    446{
    447	if (!ac97_reg_base)
    448		return 0;
    449
    450	return readl(ac97_reg_base + MODR);
    451}
    452EXPORT_SYMBOL_GPL(pxa2xx_ac97_read_modr);
    453
    454u32 pxa2xx_ac97_read_misr(void)
    455{
    456	if (!ac97_reg_base)
    457		return 0;
    458
    459	return readl(ac97_reg_base + MISR);
    460}
    461EXPORT_SYMBOL_GPL(pxa2xx_ac97_read_misr);
    462
    463MODULE_AUTHOR("Nicolas Pitre");
    464MODULE_DESCRIPTION("Intel/Marvell PXA sound library");
    465MODULE_LICENSE("GPL");
    466