From c975e472ec12392a0c34de1350e634310f8a1dea Mon Sep 17 00:00:00 2001 From: Hans de Goede Date: Fri, 13 Apr 2018 14:54:17 +0200 Subject: ACPI / LPSS: Only call pwm_add_table() for Bay Trail PWM if PMIC HRV is 2 The Point of View mobii wintab p800w Bay Trail tablet comes with a Crystal Cove PMIC, yet uses the LPSS PWM for backlight control, rather then the Crystal Cove's PWM, so we need to call pwm_add_table() to add a pwm_backlight mapping for the LPSS pwm despite there being an INT33FD ACPI device present. On all Bay Trail devices the _HRV object of the INT33FD ACPI device will normally return 2, to indicate the Bay Trail variant of the CRC PMIC is present, except on this tablet where _HRV is 0xffff. I guess this is a hack to make the windows Crystal Cove PWM driver not bind. Out of the 44 DSTDs with an INT33FD device in there which I have (from different model devices) only the pov mobii wintab p800w uses 0xffff for the HRV. The byt_pwm_setup code calls acpi_dev_present to check for the presence of a INT33FD ACPI device which indicates that a CRC PMIC is present and if the INT33FD ACPI device is present then byt_pwm_setup will not add a pwm_backlight mapping for the LPSS pwm, so that the CRC PWM will get used instead. acpi_dev_present has a hrv parameter, this commit make us pass 2 instead of -1, so that things still match on normal tablets, but on this special case with its _HRV of 0xffff, the check will now fail so that the pwm_backlight mapping for the LPSS pwm gets added fixing backlight brightness control on this device. Signed-off-by: Hans de Goede Reviewed-by: Andy Shevchenko Signed-off-by: Rafael J. Wysocki --- drivers/acpi/acpi_lpss.c | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/drivers/acpi/acpi_lpss.c b/drivers/acpi/acpi_lpss.c index 2bcffec8dbf0..cb6ac5c65c2e 100644 --- a/drivers/acpi/acpi_lpss.c +++ b/drivers/acpi/acpi_lpss.c @@ -69,6 +69,10 @@ ACPI_MODULE_NAME("acpi_lpss"); #define LPSS_SAVE_CTX BIT(4) #define LPSS_NO_D3_DELAY BIT(5) +/* Crystal Cove PMIC shares same ACPI ID between different platforms */ +#define BYT_CRC_HRV 2 +#define CHT_CRC_HRV 3 + struct lpss_private_data; struct lpss_device_desc { @@ -162,7 +166,7 @@ static void byt_pwm_setup(struct lpss_private_data *pdata) if (!adev->pnp.unique_id || strcmp(adev->pnp.unique_id, "1")) return; - if (!acpi_dev_present("INT33FD", NULL, -1)) + if (!acpi_dev_present("INT33FD", NULL, BYT_CRC_HRV)) pwm_add_table(byt_pwm_lookup, ARRAY_SIZE(byt_pwm_lookup)); } -- cgit v1.2.3 From 904aaf8050439510fb48cafb26a91034b0e7e615 Mon Sep 17 00:00:00 2001 From: Al Stone Date: Mon, 30 Apr 2018 18:39:05 -0600 Subject: ACPI / tables: improve comments regarding acpi_parse_entries_array() I found the description of the table_size argument to the function acpi_parse_entries_array() unclear and ambiguous. This is a minor documentation change to improve that description so I don't misuse the argument again in the future, and it is hopefully clearer to other future users. Signed-off-by: Al Stone [ rjw: Subject ] Signed-off-by: Rafael J. Wysocki --- drivers/acpi/tables.c | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/drivers/acpi/tables.c b/drivers/acpi/tables.c index 849c4fb19b03..4a3410aa6540 100644 --- a/drivers/acpi/tables.c +++ b/drivers/acpi/tables.c @@ -222,7 +222,7 @@ void acpi_table_print_madt_entry(struct acpi_subtable_header *header) * acpi_parse_entries_array - for each proc_num find a suitable subtable * * @id: table id (for debugging purposes) - * @table_size: single entry size + * @table_size: size of the root table * @table_header: where does the table start? * @proc: array of acpi_subtable_proc struct containing entry id * and associated handler with it @@ -233,6 +233,11 @@ void acpi_table_print_madt_entry(struct acpi_subtable_header *header) * on it. Assumption is that there's only single handler for particular * entry id. * + * The table_size is not the size of the complete ACPI table (the length + * field in the header struct), but only the size of the root table; i.e., + * the offset from the very first byte of the complete ACPI table, to the + * first byte of the very first subtable. + * * On success returns sum of all matching entries for all proc handlers. * Otherwise, -ENODEV or -EINVAL is returned. */ @@ -400,7 +405,7 @@ int __init acpi_table_parse(char *id, acpi_tbl_table_handler handler) return -ENODEV; } -/* +/* * The BIOS is supposed to supply a single APIC/MADT, * but some report two. Provide a knob to use either. * (don't you wish instance 0 and 1 were not the same?) -- cgit v1.2.3 From 421bf6a1f061a6edba47e5e7a5458f29eb791de9 Mon Sep 17 00:00:00 2001 From: Akshu Agrawal Date: Wed, 9 May 2018 17:59:00 +0800 Subject: clk: x86: Add ST oscout platform clock Stoney SoC provides oscout clock. This clock can support 25Mhz and 48Mhz of frequency. The clock is available for general system use. Signed-off-by: Akshu Agrawal Reviewed-by: Daniel Kurtz Reviewed-by: Stephen Boyd Signed-off-by: Rafael J. Wysocki --- drivers/clk/x86/Makefile | 3 +- drivers/clk/x86/clk-st.c | 77 ++++++++++++++++++++++++++++++++++++ include/linux/platform_data/clk-st.h | 17 ++++++++ 3 files changed, 96 insertions(+), 1 deletion(-) create mode 100644 drivers/clk/x86/clk-st.c create mode 100644 include/linux/platform_data/clk-st.h diff --git a/drivers/clk/x86/Makefile b/drivers/clk/x86/Makefile index 1367afb03858..00303bc05415 100644 --- a/drivers/clk/x86/Makefile +++ b/drivers/clk/x86/Makefile @@ -1,3 +1,4 @@ +obj-$(CONFIG_PMC_ATOM) += clk-pmc-atom.o +obj-$(CONFIG_X86_AMD_PLATFORM_DEVICE) += clk-st.o clk-x86-lpss-objs := clk-lpt.o obj-$(CONFIG_X86_INTEL_LPSS) += clk-x86-lpss.o -obj-$(CONFIG_PMC_ATOM) += clk-pmc-atom.o diff --git a/drivers/clk/x86/clk-st.c b/drivers/clk/x86/clk-st.c new file mode 100644 index 000000000000..fb62f3938008 --- /dev/null +++ b/drivers/clk/x86/clk-st.c @@ -0,0 +1,77 @@ +// SPDX-License-Identifier: MIT +/* + * clock framework for AMD Stoney based clocks + * + * Copyright 2018 Advanced Micro Devices, Inc. + */ + +#include +#include +#include +#include +#include + +/* Clock Driving Strength 2 register */ +#define CLKDRVSTR2 0x28 +/* Clock Control 1 register */ +#define MISCCLKCNTL1 0x40 +/* Auxiliary clock1 enable bit */ +#define OSCCLKENB 2 +/* 25Mhz auxiliary output clock freq bit */ +#define OSCOUT1CLK25MHZ 16 + +#define ST_CLK_48M 0 +#define ST_CLK_25M 1 +#define ST_CLK_MUX 2 +#define ST_CLK_GATE 3 +#define ST_MAX_CLKS 4 + +static const char * const clk_oscout1_parents[] = { "clk48MHz", "clk25MHz" }; +static struct clk_hw *hws[ST_MAX_CLKS]; + +static int st_clk_probe(struct platform_device *pdev) +{ + struct st_clk_data *st_data; + + st_data = dev_get_platdata(&pdev->dev); + if (!st_data || !st_data->base) + return -EINVAL; + + hws[ST_CLK_48M] = clk_hw_register_fixed_rate(NULL, "clk48MHz", NULL, 0, + 48000000); + hws[ST_CLK_25M] = clk_hw_register_fixed_rate(NULL, "clk25MHz", NULL, 0, + 25000000); + + hws[ST_CLK_MUX] = clk_hw_register_mux(NULL, "oscout1_mux", + clk_oscout1_parents, ARRAY_SIZE(clk_oscout1_parents), + 0, st_data->base + CLKDRVSTR2, OSCOUT1CLK25MHZ, 3, 0, NULL); + + clk_set_parent(hws[ST_CLK_MUX]->clk, hws[ST_CLK_25M]->clk); + + hws[ST_CLK_GATE] = clk_hw_register_gate(NULL, "oscout1", "oscout1_mux", + 0, st_data->base + MISCCLKCNTL1, OSCCLKENB, + CLK_GATE_SET_TO_DISABLE, NULL); + + clk_hw_register_clkdev(hws[ST_CLK_GATE], "oscout1", NULL); + + return 0; +} + +static int st_clk_remove(struct platform_device *pdev) +{ + int i; + + for (i = 0; i < ST_MAX_CLKS; i++) + clk_hw_unregister(hws[i]); + return 0; +} + +static struct platform_driver st_clk_driver = { + .driver = { + .name = "clk-st", + .suppress_bind_attrs = true, + }, + .probe = st_clk_probe, + .remove = st_clk_remove, +}; +builtin_platform_driver(st_clk_driver); diff --git a/include/linux/platform_data/clk-st.h b/include/linux/platform_data/clk-st.h new file mode 100644 index 000000000000..7cdb6a402b35 --- /dev/null +++ b/include/linux/platform_data/clk-st.h @@ -0,0 +1,17 @@ +/* SPDX-License-Identifier: MIT */ +/* + * clock framework for AMD Stoney based clock + * + * Copyright 2018 Advanced Micro Devices, Inc. + */ + +#ifndef __CLK_ST_H +#define __CLK_ST_H + +#include + +struct st_clk_data { + void __iomem *base; +}; + +#endif /* __CLK_ST_H */ -- cgit v1.2.3 From 3f4ba94e3615fe6f8a82e3a5f30677347d15130f Mon Sep 17 00:00:00 2001 From: Akshu Agrawal Date: Wed, 9 May 2018 17:59:01 +0800 Subject: ACPI: APD: Add AMD misc clock handler support AMD SoC exposes clock for general purpose use. The clock registration is done in clk-st driver. The MMIO mapping are passed on to the clock driver for accessing the registers. The misc clock handler will create MMIO mappings to access the clock registers and enable the clock driver to expose the clock for use of drivers which will connect to it. Signed-off-by: Akshu Agrawal Reviewed-by: Daniel Kurtz Signed-off-by: Rafael J. Wysocki --- drivers/acpi/acpi_apd.c | 47 +++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 47 insertions(+) diff --git a/drivers/acpi/acpi_apd.c b/drivers/acpi/acpi_apd.c index d553b0087947..2664452fa112 100644 --- a/drivers/acpi/acpi_apd.c +++ b/drivers/acpi/acpi_apd.c @@ -11,6 +11,7 @@ */ #include +#include #include #include #include @@ -72,6 +73,47 @@ static int acpi_apd_setup(struct apd_private_data *pdata) } #ifdef CONFIG_X86_AMD_PLATFORM_DEVICE + +static int misc_check_res(struct acpi_resource *ares, void *data) +{ + struct resource res; + + return !acpi_dev_resource_memory(ares, &res); +} + +static int st_misc_setup(struct apd_private_data *pdata) +{ + struct acpi_device *adev = pdata->adev; + struct platform_device *clkdev; + struct st_clk_data *clk_data; + struct resource_entry *rentry; + struct list_head resource_list; + int ret; + + clk_data = devm_kzalloc(&adev->dev, sizeof(*clk_data), GFP_KERNEL); + if (!clk_data) + return -ENOMEM; + + INIT_LIST_HEAD(&resource_list); + ret = acpi_dev_get_resources(adev, &resource_list, misc_check_res, + NULL); + if (ret < 0) + return -ENOENT; + + list_for_each_entry(rentry, &resource_list, node) { + clk_data->base = devm_ioremap(&adev->dev, rentry->res->start, + resource_size(rentry->res)); + break; + } + + acpi_dev_free_resource_list(&resource_list); + + clkdev = platform_device_register_data(&adev->dev, "clk-st", + PLATFORM_DEVID_NONE, clk_data, + sizeof(*clk_data)); + return PTR_ERR_OR_ZERO(clkdev); +} + static const struct apd_device_desc cz_i2c_desc = { .setup = acpi_apd_setup, .fixed_clk_rate = 133000000, @@ -94,6 +136,10 @@ static const struct apd_device_desc cz_uart_desc = { .fixed_clk_rate = 48000000, .properties = uart_properties, }; + +static const struct apd_device_desc st_misc_desc = { + .setup = st_misc_setup, +}; #endif #ifdef CONFIG_ARM64 @@ -179,6 +225,7 @@ static const struct acpi_device_id acpi_apd_device_ids[] = { { "AMD0020", APD_ADDR(cz_uart_desc) }, { "AMDI0020", APD_ADDR(cz_uart_desc) }, { "AMD0030", }, + { "AMD0040", APD_ADDR(st_misc_desc)}, #endif #ifdef CONFIG_ARM64 { "APMC0D0F", APD_ADDR(xgene_i2c_desc) }, -- cgit v1.2.3