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

arche-apb-ctrl.c (12143B)


      1// SPDX-License-Identifier: GPL-2.0
      2/*
      3 * Arche Platform driver to control APB.
      4 *
      5 * Copyright 2014-2015 Google Inc.
      6 * Copyright 2014-2015 Linaro Ltd.
      7 */
      8
      9#include <linux/clk.h>
     10#include <linux/delay.h>
     11#include <linux/gpio/consumer.h>
     12#include <linux/interrupt.h>
     13#include <linux/of_irq.h>
     14#include <linux/module.h>
     15#include <linux/pinctrl/consumer.h>
     16#include <linux/platform_device.h>
     17#include <linux/pm.h>
     18#include <linux/regulator/consumer.h>
     19#include <linux/spinlock.h>
     20#include "arche_platform.h"
     21
     22static void apb_bootret_deassert(struct device *dev);
     23
     24struct arche_apb_ctrl_drvdata {
     25	/* Control GPIO signals to and from AP <=> AP Bridges */
     26	struct gpio_desc *resetn;
     27	struct gpio_desc *boot_ret;
     28	struct gpio_desc *pwroff;
     29	struct gpio_desc *wake_in;
     30	struct gpio_desc *wake_out;
     31	struct gpio_desc *pwrdn;
     32
     33	enum arche_platform_state state;
     34	bool init_disabled;
     35
     36	struct regulator *vcore;
     37	struct regulator *vio;
     38
     39	struct gpio_desc *clk_en;
     40	struct clk *clk;
     41
     42	struct pinctrl *pinctrl;
     43	struct pinctrl_state *pin_default;
     44
     45	/* V2: SPI Bus control  */
     46	struct gpio_desc *spi_en;
     47	bool spi_en_polarity_high;
     48};
     49
     50/*
     51 * Note that these low level api's are active high
     52 */
     53static inline void deassert_reset(struct gpio_desc *gpio)
     54{
     55	gpiod_set_raw_value(gpio, 1);
     56}
     57
     58static inline void assert_reset(struct gpio_desc *gpio)
     59{
     60	gpiod_set_raw_value(gpio, 0);
     61}
     62
     63/*
     64 * Note: Please do not modify the below sequence, as it is as per the spec
     65 */
     66static int coldboot_seq(struct platform_device *pdev)
     67{
     68	struct device *dev = &pdev->dev;
     69	struct arche_apb_ctrl_drvdata *apb = platform_get_drvdata(pdev);
     70	int ret;
     71
     72	if (apb->init_disabled ||
     73	    apb->state == ARCHE_PLATFORM_STATE_ACTIVE)
     74		return 0;
     75
     76	/* Hold APB in reset state */
     77	assert_reset(apb->resetn);
     78
     79	if (apb->state == ARCHE_PLATFORM_STATE_FW_FLASHING && apb->spi_en)
     80		devm_gpiod_put(dev, apb->spi_en);
     81
     82	/* Enable power to APB */
     83	if (!IS_ERR(apb->vcore)) {
     84		ret = regulator_enable(apb->vcore);
     85		if (ret) {
     86			dev_err(dev, "failed to enable core regulator\n");
     87			return ret;
     88		}
     89	}
     90
     91	if (!IS_ERR(apb->vio)) {
     92		ret = regulator_enable(apb->vio);
     93		if (ret) {
     94			dev_err(dev, "failed to enable IO regulator\n");
     95			return ret;
     96		}
     97	}
     98
     99	apb_bootret_deassert(dev);
    100
    101	/* On DB3 clock was not mandatory */
    102	if (apb->clk_en)
    103		gpiod_set_value(apb->clk_en, 1);
    104
    105	usleep_range(100, 200);
    106
    107	/* deassert reset to APB : Active-low signal */
    108	deassert_reset(apb->resetn);
    109
    110	apb->state = ARCHE_PLATFORM_STATE_ACTIVE;
    111
    112	return 0;
    113}
    114
    115static int fw_flashing_seq(struct platform_device *pdev)
    116{
    117	struct device *dev = &pdev->dev;
    118	struct arche_apb_ctrl_drvdata *apb = platform_get_drvdata(pdev);
    119	int ret;
    120
    121	if (apb->init_disabled ||
    122	    apb->state == ARCHE_PLATFORM_STATE_FW_FLASHING)
    123		return 0;
    124
    125	ret = regulator_enable(apb->vcore);
    126	if (ret) {
    127		dev_err(dev, "failed to enable core regulator\n");
    128		return ret;
    129	}
    130
    131	ret = regulator_enable(apb->vio);
    132	if (ret) {
    133		dev_err(dev, "failed to enable IO regulator\n");
    134		return ret;
    135	}
    136
    137	if (apb->spi_en) {
    138		unsigned long flags;
    139
    140		if (apb->spi_en_polarity_high)
    141			flags = GPIOD_OUT_HIGH;
    142		else
    143			flags = GPIOD_OUT_LOW;
    144
    145		apb->spi_en = devm_gpiod_get(dev, "spi-en", flags);
    146		if (IS_ERR(apb->spi_en)) {
    147			ret = PTR_ERR(apb->spi_en);
    148			dev_err(dev, "Failed requesting SPI bus en GPIO: %d\n",
    149				ret);
    150			return ret;
    151		}
    152	}
    153
    154	/* for flashing device should be in reset state */
    155	assert_reset(apb->resetn);
    156	apb->state = ARCHE_PLATFORM_STATE_FW_FLASHING;
    157
    158	return 0;
    159}
    160
    161static int standby_boot_seq(struct platform_device *pdev)
    162{
    163	struct device *dev = &pdev->dev;
    164	struct arche_apb_ctrl_drvdata *apb = platform_get_drvdata(pdev);
    165
    166	if (apb->init_disabled)
    167		return 0;
    168
    169	/*
    170	 * Even if it is in OFF state,
    171	 * then we do not want to change the state
    172	 */
    173	if (apb->state == ARCHE_PLATFORM_STATE_STANDBY ||
    174	    apb->state == ARCHE_PLATFORM_STATE_OFF)
    175		return 0;
    176
    177	if (apb->state == ARCHE_PLATFORM_STATE_FW_FLASHING && apb->spi_en)
    178		devm_gpiod_put(dev, apb->spi_en);
    179
    180	/*
    181	 * As per WDM spec, do nothing
    182	 *
    183	 * Pasted from WDM spec,
    184	 *  - A falling edge on POWEROFF_L is detected (a)
    185	 *  - WDM enters standby mode, but no output signals are changed
    186	 */
    187
    188	/* TODO: POWEROFF_L is input to WDM module  */
    189	apb->state = ARCHE_PLATFORM_STATE_STANDBY;
    190	return 0;
    191}
    192
    193static void poweroff_seq(struct platform_device *pdev)
    194{
    195	struct device *dev = &pdev->dev;
    196	struct arche_apb_ctrl_drvdata *apb = platform_get_drvdata(pdev);
    197
    198	if (apb->init_disabled || apb->state == ARCHE_PLATFORM_STATE_OFF)
    199		return;
    200
    201	if (apb->state == ARCHE_PLATFORM_STATE_FW_FLASHING && apb->spi_en)
    202		devm_gpiod_put(dev, apb->spi_en);
    203
    204	/* disable the clock */
    205	if (apb->clk_en)
    206		gpiod_set_value(apb->clk_en, 0);
    207
    208	if (!IS_ERR(apb->vcore) && regulator_is_enabled(apb->vcore) > 0)
    209		regulator_disable(apb->vcore);
    210
    211	if (!IS_ERR(apb->vio) && regulator_is_enabled(apb->vio) > 0)
    212		regulator_disable(apb->vio);
    213
    214	/* As part of exit, put APB back in reset state */
    215	assert_reset(apb->resetn);
    216	apb->state = ARCHE_PLATFORM_STATE_OFF;
    217
    218	/* TODO: May have to send an event to SVC about this exit */
    219}
    220
    221static void apb_bootret_deassert(struct device *dev)
    222{
    223	struct arche_apb_ctrl_drvdata *apb = dev_get_drvdata(dev);
    224
    225	gpiod_set_value(apb->boot_ret, 0);
    226}
    227
    228int apb_ctrl_coldboot(struct device *dev)
    229{
    230	return coldboot_seq(to_platform_device(dev));
    231}
    232
    233int apb_ctrl_fw_flashing(struct device *dev)
    234{
    235	return fw_flashing_seq(to_platform_device(dev));
    236}
    237
    238int apb_ctrl_standby_boot(struct device *dev)
    239{
    240	return standby_boot_seq(to_platform_device(dev));
    241}
    242
    243void apb_ctrl_poweroff(struct device *dev)
    244{
    245	poweroff_seq(to_platform_device(dev));
    246}
    247
    248static ssize_t state_store(struct device *dev,
    249			   struct device_attribute *attr,
    250			   const char *buf, size_t count)
    251{
    252	struct platform_device *pdev = to_platform_device(dev);
    253	struct arche_apb_ctrl_drvdata *apb = platform_get_drvdata(pdev);
    254	int ret = 0;
    255	bool is_disabled;
    256
    257	if (sysfs_streq(buf, "off")) {
    258		if (apb->state == ARCHE_PLATFORM_STATE_OFF)
    259			return count;
    260
    261		poweroff_seq(pdev);
    262	} else if (sysfs_streq(buf, "active")) {
    263		if (apb->state == ARCHE_PLATFORM_STATE_ACTIVE)
    264			return count;
    265
    266		poweroff_seq(pdev);
    267		is_disabled = apb->init_disabled;
    268		apb->init_disabled = false;
    269		ret = coldboot_seq(pdev);
    270		if (ret)
    271			apb->init_disabled = is_disabled;
    272	} else if (sysfs_streq(buf, "standby")) {
    273		if (apb->state == ARCHE_PLATFORM_STATE_STANDBY)
    274			return count;
    275
    276		ret = standby_boot_seq(pdev);
    277	} else if (sysfs_streq(buf, "fw_flashing")) {
    278		if (apb->state == ARCHE_PLATFORM_STATE_FW_FLASHING)
    279			return count;
    280
    281		/*
    282		 * First we want to make sure we power off everything
    283		 * and then enter FW flashing state
    284		 */
    285		poweroff_seq(pdev);
    286		ret = fw_flashing_seq(pdev);
    287	} else {
    288		dev_err(dev, "unknown state\n");
    289		ret = -EINVAL;
    290	}
    291
    292	return ret ? ret : count;
    293}
    294
    295static ssize_t state_show(struct device *dev,
    296			  struct device_attribute *attr, char *buf)
    297{
    298	struct arche_apb_ctrl_drvdata *apb = dev_get_drvdata(dev);
    299
    300	switch (apb->state) {
    301	case ARCHE_PLATFORM_STATE_OFF:
    302		return sprintf(buf, "off%s\n",
    303				apb->init_disabled ? ",disabled" : "");
    304	case ARCHE_PLATFORM_STATE_ACTIVE:
    305		return sprintf(buf, "active\n");
    306	case ARCHE_PLATFORM_STATE_STANDBY:
    307		return sprintf(buf, "standby\n");
    308	case ARCHE_PLATFORM_STATE_FW_FLASHING:
    309		return sprintf(buf, "fw_flashing\n");
    310	default:
    311		return sprintf(buf, "unknown state\n");
    312	}
    313}
    314
    315static DEVICE_ATTR_RW(state);
    316
    317static int apb_ctrl_get_devtree_data(struct platform_device *pdev,
    318				     struct arche_apb_ctrl_drvdata *apb)
    319{
    320	struct device *dev = &pdev->dev;
    321	int ret;
    322
    323	apb->resetn = devm_gpiod_get(dev, "reset", GPIOD_OUT_LOW);
    324	if (IS_ERR(apb->resetn)) {
    325		ret = PTR_ERR(apb->resetn);
    326		dev_err(dev, "Failed requesting reset GPIO: %d\n", ret);
    327		return ret;
    328	}
    329
    330	apb->boot_ret = devm_gpiod_get(dev, "boot-ret", GPIOD_OUT_LOW);
    331	if (IS_ERR(apb->boot_ret)) {
    332		ret = PTR_ERR(apb->boot_ret);
    333		dev_err(dev, "Failed requesting bootret GPIO: %d\n", ret);
    334		return ret;
    335	}
    336
    337	/* It's not mandatory to support power management interface */
    338	apb->pwroff = devm_gpiod_get_optional(dev, "pwr-off", GPIOD_IN);
    339	if (IS_ERR(apb->pwroff)) {
    340		ret = PTR_ERR(apb->pwroff);
    341		dev_err(dev, "Failed requesting pwroff_n GPIO: %d\n", ret);
    342		return ret;
    343	}
    344
    345	/* Do not make clock mandatory as of now (for DB3) */
    346	apb->clk_en = devm_gpiod_get_optional(dev, "clock-en", GPIOD_OUT_LOW);
    347	if (IS_ERR(apb->clk_en)) {
    348		ret = PTR_ERR(apb->clk_en);
    349		dev_err(dev, "Failed requesting APB clock en GPIO: %d\n", ret);
    350		return ret;
    351	}
    352
    353	apb->pwrdn = devm_gpiod_get(dev, "pwr-down", GPIOD_OUT_LOW);
    354	if (IS_ERR(apb->pwrdn)) {
    355		ret = PTR_ERR(apb->pwrdn);
    356		dev_warn(dev, "Failed requesting power down GPIO: %d\n", ret);
    357		return ret;
    358	}
    359
    360	/* Regulators are optional, as we may have fixed supply coming in */
    361	apb->vcore = devm_regulator_get(dev, "vcore");
    362	if (IS_ERR(apb->vcore))
    363		dev_warn(dev, "no core regulator found\n");
    364
    365	apb->vio = devm_regulator_get(dev, "vio");
    366	if (IS_ERR(apb->vio))
    367		dev_warn(dev, "no IO regulator found\n");
    368
    369	apb->pinctrl = devm_pinctrl_get(&pdev->dev);
    370	if (IS_ERR(apb->pinctrl)) {
    371		dev_err(&pdev->dev, "could not get pinctrl handle\n");
    372		return PTR_ERR(apb->pinctrl);
    373	}
    374	apb->pin_default = pinctrl_lookup_state(apb->pinctrl, "default");
    375	if (IS_ERR(apb->pin_default)) {
    376		dev_err(&pdev->dev, "could not get default pin state\n");
    377		return PTR_ERR(apb->pin_default);
    378	}
    379
    380	/* Only applicable for platform >= V2 */
    381	if (of_property_read_bool(pdev->dev.of_node, "gb,spi-en-active-high"))
    382		apb->spi_en_polarity_high = true;
    383
    384	return 0;
    385}
    386
    387static int arche_apb_ctrl_probe(struct platform_device *pdev)
    388{
    389	int ret;
    390	struct arche_apb_ctrl_drvdata *apb;
    391	struct device *dev = &pdev->dev;
    392
    393	apb = devm_kzalloc(&pdev->dev, sizeof(*apb), GFP_KERNEL);
    394	if (!apb)
    395		return -ENOMEM;
    396
    397	ret = apb_ctrl_get_devtree_data(pdev, apb);
    398	if (ret) {
    399		dev_err(dev, "failed to get apb devicetree data %d\n", ret);
    400		return ret;
    401	}
    402
    403	/* Initially set APB to OFF state */
    404	apb->state = ARCHE_PLATFORM_STATE_OFF;
    405	/* Check whether device needs to be enabled on boot */
    406	if (of_property_read_bool(pdev->dev.of_node, "arche,init-disable"))
    407		apb->init_disabled = true;
    408
    409	platform_set_drvdata(pdev, apb);
    410
    411	/* Create sysfs interface to allow user to change state dynamically */
    412	ret = device_create_file(dev, &dev_attr_state);
    413	if (ret) {
    414		dev_err(dev, "failed to create state file in sysfs\n");
    415		return ret;
    416	}
    417
    418	dev_info(&pdev->dev, "Device registered successfully\n");
    419	return 0;
    420}
    421
    422static int arche_apb_ctrl_remove(struct platform_device *pdev)
    423{
    424	device_remove_file(&pdev->dev, &dev_attr_state);
    425	poweroff_seq(pdev);
    426	platform_set_drvdata(pdev, NULL);
    427
    428	return 0;
    429}
    430
    431static int __maybe_unused arche_apb_ctrl_suspend(struct device *dev)
    432{
    433	/*
    434	 * If timing profile permits, we may shutdown bridge
    435	 * completely
    436	 *
    437	 * TODO: sequence ??
    438	 *
    439	 * Also, need to make sure we meet precondition for unipro suspend
    440	 * Precondition: Definition ???
    441	 */
    442	return 0;
    443}
    444
    445static int __maybe_unused arche_apb_ctrl_resume(struct device *dev)
    446{
    447	/*
    448	 * At least for ES2 we have to meet the delay requirement between
    449	 * unipro switch and AP bridge init, depending on whether bridge is in
    450	 * OFF state or standby state.
    451	 *
    452	 * Based on whether bridge is in standby or OFF state we may have to
    453	 * assert multiple signals. Please refer to WDM spec, for more info.
    454	 *
    455	 */
    456	return 0;
    457}
    458
    459static void arche_apb_ctrl_shutdown(struct platform_device *pdev)
    460{
    461	apb_ctrl_poweroff(&pdev->dev);
    462}
    463
    464static SIMPLE_DEV_PM_OPS(arche_apb_ctrl_pm_ops, arche_apb_ctrl_suspend,
    465			 arche_apb_ctrl_resume);
    466
    467static const struct of_device_id arche_apb_ctrl_of_match[] = {
    468	{ .compatible = "usbffff,2", },
    469	{ },
    470};
    471
    472static struct platform_driver arche_apb_ctrl_device_driver = {
    473	.probe		= arche_apb_ctrl_probe,
    474	.remove		= arche_apb_ctrl_remove,
    475	.shutdown	= arche_apb_ctrl_shutdown,
    476	.driver		= {
    477		.name	= "arche-apb-ctrl",
    478		.pm	= &arche_apb_ctrl_pm_ops,
    479		.of_match_table = arche_apb_ctrl_of_match,
    480	}
    481};
    482
    483int __init arche_apb_init(void)
    484{
    485	return platform_driver_register(&arche_apb_ctrl_device_driver);
    486}
    487
    488void __exit arche_apb_exit(void)
    489{
    490	platform_driver_unregister(&arche_apb_ctrl_device_driver);
    491}