History

media: staging: atomisp: use clock framework for camera clocks

The Atom ISP driver initializes and configures PMC clocks which are already handled by the clock framework. Remove all legacy vlv2_platform_clock stuff and move to the clk API to avoid conflicts, e.g. with audio machine drivers enabling the MCLK for external codecs Fixes: a49d25364dfb ("staging/atomisp: Add support for the Intel IPU v2")

Pierre-Louis Bossart committed 9 years ago

Commit d5426f41 parent abe51397 files · +52 −332Browse files

Unified · Split

7 files
  1. drivers/staging/media/atomisp/Kconfig +1 −0
  2. drivers/staging/media/atomisp/platform/Makefile +0 −1
  3. drivers/staging/media/atomisp/platform/clock/Makefile +0 −6
  4. drivers/staging/media/atomisp/platform/clock/platform_vlv2_plat_clk.c +0 −40
  5. drivers/staging/media/atomisp/platform/clock/platform_vlv2_plat_clk.h +0 −26
  6. drivers/staging/media/atomisp/platform/clock/vlv2_plat_clock.c +0 −247
  7. drivers/staging/media/atomisp/platform/intel-mid/atomisp_gmin_platform.c +51 −12
drivers/staging/media/atomisp/Kconfig+1−0
@@ -1,6 +1,7 @@
11 menuconfig INTEL_ATOMISP
22 bool "Enable support to Intel MIPI camera drivers"
33 depends on X86 && EFI && MEDIA_CONTROLLER && PCI && ACPI
4+ select COMMON_CLK
45 help
56 Enable support for the Intel ISP2 camera interfaces and MIPI
67 sensor drivers.
drivers/staging/media/atomisp/platform/Makefile+0−1
@@ -2,5 +2,4 @@ · 1 unmodified line
22 # Makefile for camera drivers.
33 #
44
5−obj-$(CONFIG_INTEL_ATOMISP) += clock/
65 obj-$(CONFIG_INTEL_ATOMISP) += intel-mid/
drivers/staging/media/atomisp/platform/clock/Makefile+0−6
@@ -1,6 +0,0 @@
1−#
2−# Makefile for clock devices.
3−#
4−
5−obj-$(CONFIG_INTEL_ATOMISP) += vlv2_plat_clock.o
6−obj-$(CONFIG_INTEL_ATOMISP) += platform_vlv2_plat_clk.o
drivers/staging/media/atomisp/platform/clock/platform_vlv2_plat_clk.c+0−40
@@ -1,40 +0,0 @@
1−/*
2− * platform_vlv2_plat_clk.c - VLV2 platform clock driver
3− * Copyright (C) 2013 Intel Corporation
4− *
5− * Author: Asutosh Pathak <asutosh.pathak@intel.com>
6− * Author: Chandra Sekhar Anagani <chandra.sekhar.anagani@intel.com>
7− * Author: Sergio Aguirre <sergio.a.aguirre.rodriguez@intel.com>
8− *
9− * This program is free software; you can redistribute it and/or modify
10− * it under the terms of the GNU General Public License as published by
11− * the Free Software Foundation; version 2 of the License.
12− *
13− * This program is distributed in the hope that it will be useful, but
14− * WITHOUT ANY WARRANTY; without even the implied warranty of
15− * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
16− * General Public License for more details.
17− *
18− */
19−
20−#include <linux/device.h>
21−#include <linux/err.h>
22−#include <linux/module.h>
23−#include <linux/platform_device.h>
24−#include <linux/printk.h>
25−
26−static int __init vlv2_plat_clk_init(void)
27−{
28− struct platform_device *pdev;
29−
30− pdev = platform_device_register_simple("vlv2_plat_clk", -1, NULL, 0);
31− if (IS_ERR(pdev)) {
32− pr_err("platform_vlv2_plat_clk:register failed: %ld\n",
33− PTR_ERR(pdev));
34− return PTR_ERR(pdev);
35− }
36−
37− return 0;
38−}
39−
40−device_initcall(vlv2_plat_clk_init);
drivers/staging/media/atomisp/platform/clock/platform_vlv2_plat_clk.h+0−26
@@ -1,26 +0,0 @@
1−/*
2− * platform_vlv2_plat_clk.h: platform clock driver library header file
3− * Copyright (C) 2013 Intel Corporation
4− *
5− * Author: Asutosh Pathak <asutosh.pathak@intel.com>
6− * Author: Chandra Sekhar Anagani <chandra.sekhar.anagani@intel.com>
7− * Author: Sergio Aguirre <sergio.a.aguirre.rodriguez@intel.com>
8− *
9− * This program is free software; you can redistribute it and/or modify
10− * it under the terms of the GNU General Public License as published by
11− * the Free Software Foundation; version 2 of the License.
12− *
13− * This program is distributed in the hope that it will be useful, but
14− * WITHOUT ANY WARRANTY; without even the implied warranty of
15− * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
16− * General Public License for more details.
17− *
18− */
19−#ifndef _PLATFORM_VLV2_PLAT_CLK_H_
20−#define _PLATFORM_VLV2_PLAT_CLK_H_
21−
22−#include <linux/sfi.h>
23−
24−extern void __init *vlv2_plat_clk_device_platform_data(
25− void *info) __attribute__((weak));
26−#endif
drivers/staging/media/atomisp/platform/clock/vlv2_plat_clock.c+0−247
@@ -1,247 +0,0 @@
1−/*
2− * vlv2_plat_clock.c - VLV2 platform clock driver
3− * Copyright (C) 2013 Intel Corporation
4− *
5− * Author: Asutosh Pathak <asutosh.pathak@intel.com>
6− * Author: Chandra Sekhar Anagani <chandra.sekhar.anagani@intel.com>
7− *
8− * This program is free software; you can redistribute it and/or modify
9− * it under the terms of the GNU General Public License as published by
10− * the Free Software Foundation; version 2 of the License.
11− *
12− * This program is distributed in the hope that it will be useful, but
13− * WITHOUT ANY WARRANTY; without even the implied warranty of
14− * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15− * General Public License for more details.
16− *
17− * You should have received a copy of the GNU General Public License along
18− * with this program; if not, write to the Free Software Foundation, Inc.,
19− * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
20− */
21−
22−#include <linux/err.h>
23−#include <linux/io.h>
24−#include <linux/init.h>
25−#include <linux/platform_device.h>
26−#include "../../include/linux/vlv2_plat_clock.h"
27−
28−/* NOTE: Most of below constants could come from platform data.
29− * To be fixed when appropriate ACPI support comes.
30− */
31−#define VLV2_PMC_CLK_BASE_ADDRESS 0xfed03060
32−#define PLT_CLK_CTL_OFFSET(x) (0x04 * (x))
33−
34−#define CLK_CONFG_BIT_POS 0
35−#define CLK_CONFG_BIT_LEN 2
36−#define CLK_CONFG_D3_GATED 0
37−#define CLK_CONFG_FORCE_ON 1
38−#define CLK_CONFG_FORCE_OFF 2
39−
40−#define CLK_FREQ_TYPE_BIT_POS 2
41−#define CLK_FREQ_TYPE_BIT_LEN 1
42−#define CLK_FREQ_TYPE_XTAL 0 /* 25 MHz */
43−#define CLK_FREQ_TYPE_PLL 1 /* 19.2 MHz */
44−
45−#define MAX_CLK_COUNT 5
46−
47−/* Helper macros to manipulate bitfields */
48−#define REG_MASK(n) (((1 << (n##_BIT_LEN)) - 1) << (n##_BIT_POS))
49−#define REG_SET_FIELD(r, n, v) (((r) & ~REG_MASK(n)) | \
50− (((v) << (n##_BIT_POS)) & REG_MASK(n)))
51−#define REG_GET_FIELD(r, n) (((r) & REG_MASK(n)) >> n##_BIT_POS)
52−/*
53− * vlv2 platform has 6 platform clocks, controlled by 4 byte registers
54− * Total size required for mapping is 6*4 = 24 bytes
55− */
56−#define PMC_MAP_SIZE 24
57−
58−static DEFINE_MUTEX(clk_mutex);
59−static void __iomem *pmc_base;
60−
61−/*
62− * vlv2_plat_set_clock_freq - Set clock frequency to a specified platform clock
63− * @clk_num: Platform clock number (i.e. 0, 1, 2, ...,5)
64− * @freq_type: Clock frequency (0-25 MHz(XTAL), 1-19.2 MHz(PLL) )
65− */
66−int vlv2_plat_set_clock_freq(int clk_num, int freq_type)
67−{
68− void __iomem *addr;
69−
70− if (clk_num < 0 || clk_num >= MAX_CLK_COUNT) {
71− pr_err("Clock number out of range (%d)\n", clk_num);
72− return -EINVAL;
73− }
74−
75− if (freq_type != CLK_FREQ_TYPE_XTAL &&
76− freq_type != CLK_FREQ_TYPE_PLL) {
77− pr_err("wrong clock type\n");
78− return -EINVAL;
79− }
80−
81− if (!pmc_base) {
82− pr_err("memio map is not set\n");
83− return -EINVAL;
84− }
85−
86− addr = pmc_base + PLT_CLK_CTL_OFFSET(clk_num);
87−
88− mutex_lock(&clk_mutex);
89− writel(REG_SET_FIELD(readl(addr), CLK_FREQ_TYPE, freq_type), addr);
90− mutex_unlock(&clk_mutex);
91−
92− return 0;
93−}
94−EXPORT_SYMBOL_GPL(vlv2_plat_set_clock_freq);
95−
96−/*
97− * vlv2_plat_get_clock_freq - Get the status of specified platform clock
98− * @clk_num: Platform clock number (i.e. 0, 1, 2, ...,5)
99− *
100− * Returns 0 for 25 MHz(XTAL) and 1 for 19.2 MHz(PLL)
101− */
102−int vlv2_plat_get_clock_freq(int clk_num)
103−{
104− u32 ret;
105−
106− if (clk_num < 0 || clk_num >= MAX_CLK_COUNT) {
107− pr_err("Clock number out of range (%d)\n", clk_num);
108− return -EINVAL;
109− }
110−
111− if (!pmc_base) {
112− pr_err("memio map is not set\n");
113− return -EINVAL;
114− }
115−
116− mutex_lock(&clk_mutex);
117− ret = REG_GET_FIELD(readl(pmc_base + PLT_CLK_CTL_OFFSET(clk_num)),
118− CLK_FREQ_TYPE);
119− mutex_unlock(&clk_mutex);
120− return ret;
121−}
122−EXPORT_SYMBOL_GPL(vlv2_plat_get_clock_freq);
123−
124−/*
125− * vlv2_plat_configure_clock - Configure the specified platform clock
126− * @clk_num: Platform clock number (i.e. 0, 1, 2, ...,5)
127− * @conf: Clock gating:
128− * 0 - Clock gated on D3 state
129− * 1 - Force on
130− * 2,3 - Force off
131− */
132−int vlv2_plat_configure_clock(int clk_num, u32 conf)
133−{
134− void __iomem *addr;
135−
136− if (clk_num < 0 || clk_num >= MAX_CLK_COUNT) {
137− pr_err("Clock number out of range (%d)\n", clk_num);
138− return -EINVAL;
139− }
140−
141− if (conf != CLK_CONFG_D3_GATED &&
142− conf != CLK_CONFG_FORCE_ON &&
143− conf != CLK_CONFG_FORCE_OFF) {
144− pr_err("Invalid clock configuration requested\n");
145− return -EINVAL;
146− }
147−
148− if (!pmc_base) {
149− pr_err("memio map is not set\n");
150− return -EINVAL;
151− }
152−
153− addr = pmc_base + PLT_CLK_CTL_OFFSET(clk_num);
154−
155− mutex_lock(&clk_mutex);
156− writel(REG_SET_FIELD(readl(addr), CLK_CONFG, conf), addr);
157− mutex_unlock(&clk_mutex);
158− return 0;
159−}
160−EXPORT_SYMBOL_GPL(vlv2_plat_configure_clock);
161−
162−/*
163− * vlv2_plat_get_clock_status - Get the status of specified platform clock
164− * @clk_num: Platform clock number (i.e. 0, 1, 2, ...,5)
165− *
166− * Returns 1 - On, 0 - Off
167− */
168−int vlv2_plat_get_clock_status(int clk_num)
169−{
170− int ret;
171−
172− if (clk_num < 0 || clk_num >= MAX_CLK_COUNT) {
173− pr_err("Clock number out of range (%d)\n", clk_num);
174− return -EINVAL;
175− }
176−
177− if (!pmc_base) {
178− pr_err("memio map is not set\n");
179− return -EINVAL;
180− }
181−
182− mutex_lock(&clk_mutex);
183− ret = (int)REG_GET_FIELD(readl(pmc_base + PLT_CLK_CTL_OFFSET(clk_num)),
184− CLK_CONFG);
185− mutex_unlock(&clk_mutex);
186− return ret;
187−}
188−EXPORT_SYMBOL_GPL(vlv2_plat_get_clock_status);
189−
190−static int vlv2_plat_clk_probe(struct platform_device *pdev)
191−{
192− int i = 0;
193−
194− pmc_base = ioremap_nocache(VLV2_PMC_CLK_BASE_ADDRESS, PMC_MAP_SIZE);
195− if (!pmc_base) {
196− dev_err(&pdev->dev, "I/O memory remapping failed\n");
197− return -ENOMEM;
198− }
199−
200− /* Initialize all clocks as disabled */
201− for (i = 0; i < MAX_CLK_COUNT; i++)
202− vlv2_plat_configure_clock(i, CLK_CONFG_FORCE_OFF);
203−
204− dev_info(&pdev->dev, "vlv2_plat_clk initialized\n");
205− return 0;
206−}
207−
208−static const struct platform_device_id vlv2_plat_clk_id[] = {
209− {"vlv2_plat_clk", 0},
210− {}
211−};
212−
213−static int vlv2_resume(struct device *device)
214−{
215− int i;
216−
217− /* Initialize all clocks as disabled */
218− for (i = 0; i < MAX_CLK_COUNT; i++)
219− vlv2_plat_configure_clock(i, CLK_CONFG_FORCE_OFF);
220−
221− return 0;
222−}
223−
224−static int vlv2_suspend(struct device *device)
225−{
226− return 0;
227−}
228−
229−static const struct dev_pm_ops vlv2_pm_ops = {
230− .suspend = vlv2_suspend,
231− .resume = vlv2_resume,
232−};
233−
234−static struct platform_driver vlv2_plat_clk_driver = {
235− .probe = vlv2_plat_clk_probe,
236− .id_table = vlv2_plat_clk_id,
237− .driver = {
238− .name = "vlv2_plat_clk",
239− .pm = &vlv2_pm_ops,
240− },
241−};
242−
243−static int __init vlv2_plat_clk_init(void)
244−{
245− return platform_driver_register(&vlv2_plat_clk_driver);
246−}
247−arch_initcall(vlv2_plat_clk_init);
drivers/staging/media/atomisp/platform/intel-mid/atomisp_gmin_platform.c+51−12
@@ -4,10 +4,10 @@ · 3 unmodified lines
44 #include <linux/efi.h>
55 #include <linux/pci.h>
66 #include <linux/acpi.h>
7+#include <linux/clk.h>
78 #include <linux/delay.h>
89 #include <media/v4l2-subdev.h>
910 #include <linux/mfd/intel_soc_pmic.h>
10−#include "../../include/linux/vlv2_plat_clock.h"
1111 #include <linux/regulator/consumer.h>
1212 #include <linux/gpio/consumer.h>
1313 #include <linux/gpio.h>
@@ -17,11 +17,7 @@ · 3 unmodified lines
1717
1818 #define MAX_SUBDEVS 8
1919
20−/* Should be defined in vlv2_plat_clock API, isn't: */
21−#define VLV2_CLK_PLL_19P2MHZ 1
22−#define VLV2_CLK_XTAL_19P2MHZ 0
23−#define VLV2_CLK_ON 1
24−#define VLV2_CLK_OFF 2
20+#define VLV2_CLK_PLL_19P2MHZ 1 /* XTAL on CHT */
2521 #define ELDO1_SEL_REG 0x19
2622 #define ELDO1_1P8V 0x16
2723 #define ELDO1_CTRL_SHIFT 0x00
@@ -33,6 +29,7 @@ struct gmin_subdev { · 5 unmodified lines
3329 struct v4l2_subdev *subdev;
3430 int clock_num;
3531 int clock_src;
32+ struct clk *pmc_clk;
3633 struct gpio_desc *gpio0;
3734 struct gpio_desc *gpio1;
3835 struct regulator *v1p8_reg;
@@ -344,6 +341,9 @@ static int gmin_platform_deinit(void) · 305 unmodified lines
344341 return 0;
345342 }
346343
344+#define GMIN_PMC_CLK_NAME 14 /* "pmc_plt_clk_[0..5]" */
345+static char gmin_pmc_clk_name[GMIN_PMC_CLK_NAME];
346+
347347 static struct gmin_subdev *gmin_subdev_add(struct v4l2_subdev *subdev)
348348 {
349349 int i, ret;
@@ -377,6 +377,37 @@ static struct gmin_subdev *gmin_subdev_add(struct v4l2_subdev *subdev) · 27 unmodified lines
377377 gmin_subdevs[i].gpio0 = gpiod_get_index(dev, NULL, 0, GPIOD_OUT_LOW);
378378 gmin_subdevs[i].gpio1 = gpiod_get_index(dev, NULL, 1, GPIOD_OUT_LOW);
379379
380+ /* get PMC clock with clock framework */
381+ snprintf(gmin_pmc_clk_name,
382+ sizeof(gmin_pmc_clk_name),
383+ "%s_%d", "pmc_plt_clk", gmin_subdevs[i].clock_num);
384+
385+ gmin_subdevs[i].pmc_clk = devm_clk_get(dev, gmin_pmc_clk_name);
386+ if (IS_ERR(gmin_subdevs[i].pmc_clk)) {
387+ ret = PTR_ERR(gmin_subdevs[i].pmc_clk);
388+
389+ dev_err(dev,
390+ "Failed to get clk from %s : %d\n",
391+ gmin_pmc_clk_name,
392+ ret);
393+
394+ return NULL;
395+ }
396+
397+ /*
398+ * The firmware might enable the clock at
399+ * boot (this information may or may not
400+ * be reflected in the enable clock register).
401+ * To change the rate we must disable the clock
402+ * first to cover these cases. Due to common
403+ * clock framework restrictions that do not allow
404+ * to disable a clock that has not been enabled,
405+ * we need to enable the clock first.
406+ */
407+ ret = clk_prepare_enable(gmin_subdevs[i].pmc_clk);
408+ if (!ret)
409+ clk_disable_unprepare(gmin_subdevs[i].pmc_clk);
410+
380411 if (!IS_ERR(gmin_subdevs[i].gpio0)) {
381412 ret = gpiod_direction_output(gmin_subdevs[i].gpio0, 0);
382413 if (ret)
@@ -539,13 +570,21 @@ static int gmin_flisclk_ctrl(struct v4l2_subdev *subdev, int on) · 156 unmodified lines
539570 {
540571 int ret = 0;
541572 struct gmin_subdev *gs = find_gmin_subdev(subdev);
573+ struct i2c_client *client = v4l2_get_subdevdata(subdev);
574+
575+ if (on) {
576+ ret = clk_set_rate(gs->pmc_clk, gs->clock_src);
577+
578+ if (ret)
579+ dev_err(&client->dev, "unable to set PMC rate %d\n",
580+ gs->clock_src);
542581
543− if (on)
544− ret = vlv2_plat_set_clock_freq(gs->clock_num, gs->clock_src);
545− if (ret)
546− return ret;
547− return vlv2_plat_configure_clock(gs->clock_num,
548− on ? VLV2_CLK_ON : VLV2_CLK_OFF);
582+ ret = clk_prepare_enable(gs->pmc_clk);
583+ } else {
584+ clk_disable_unprepare(gs->pmc_clk);
585+ }
586+
587+ return ret;
549588 }
550589
551590 static int gmin_csi_cfg(struct v4l2_subdev *sd, int flag)