From: Arnd Bergmann <arnd@arndb.de>
To: Mark Salter <msalter@redhat.com>
Cc: linux-arch@vger.kernel.org, Grant Likely <grant.likely@secretlab.ca>
Subject: Re: [PATCH 21/24] C6X: specific SoC support
Date: Tue, 23 Aug 2011 00:21:54 +0200 [thread overview]
Message-ID: <2642192.V7A2ih9bgf@wuerfel> (raw)
In-Reply-To: <1314043785-2880-22-git-send-email-msalter@redhat.com>
On Monday 22 August 2011 16:09:42 Mark Salter wrote:
> This patch provides the code for the four currently supported SoCs. Each SoC
> provides a struct soc_ops which contains hooks for miscellaneous functionality
> which does not fit well in any drivers. At setup_arch time, the device tree is
> probed to find the correct soc_ops struct to use.
>
> Most SoCs provide one or more sets of MMIO registers for various SoC-specific
> low-level device setup and control. the device tree is parsed at setup_arch
> time to find the base address of these registers.
>
> Signed-off-by: Mark Salter <msalter@redhat.com>
This patch (together with "C6X: general SoC support") is now the only remaining
issue that I'm a bit worried about. You made great progress on removing the
board specific files, but I think that a lot of the SoC specific code should
also be done differently. Reading through it in detail, my impression was that
it would be helpful to separate the 'dscr' driver from overall SoC code,
splitting the current soc_ops into a smaller soc_ops and a separate dscr_ops
structure. The reason for this is both because they are logically separate
things to abstract, and to allow having multiple soc designs share a common
dscr driver accounting for minor differences based on the compatible
property of the dscr node.
> +static struct clk_lookup c6455_clks[] = {
> + CLK(NULL, "pll1", &c6x_soc_pll1.sysclks[0]),
> + CLK(NULL, "pll1_sysclk2", &c6x_soc_pll1.sysclks[2]),
> + CLK(NULL, "pll1_sysclk3", &c6x_soc_pll1.sysclks[3]),
> + CLK(NULL, "pll1_sysclk4", &c6x_soc_pll1.sysclks[4]),
> + CLK(NULL, "pll1_sysclk5", &c6x_soc_pll1.sysclks[5]),
> + CLK(NULL, "core", &c6x_core_clk),
> + CLK("i2c_davinci.1", NULL, &c6x_i2c_clk),
> + CLK("watchdog", NULL, &c6x_watchdog_clk),
> + CLK("2c81800.mdio", NULL, &c6x_mdio_clk),
> + CLK("", NULL, NULL)
> +};
I haven't paid much attention to the clock rework in the ARM architecture,
but the impression that I got was these tables are only needed for
legacy drivers and that you shouldn't require them with device-tree
aware drivers and platforms. Maybe Grant can provide more insight.
> +/* device IDs passed to dscr_enable() and dscr_disable() */
> +#define DSCR_TCP 0
> +#define DSCR_VCP 1
> +#define DSCR_EMAC 2
> +#define DSCR_TIMER0 3
> +#define DSCR_TIMER1 4
> +#define DSCR_GPIO 5
> +#define DSCR_I2C 6
> +#define DSCR_BSP0 7
> +#define DSCR_BSP1 8
> +#define DSCR_HPI 9
> +#define DSCR_PCI 10
> +#define DSCR_UTOPIA 11
> +#define DSCR_SRIO 15
> +#define DSCR_EMIFA 16
> +#define DSCR_DDR2 17
Where do these numbers come from? I can't see if they are hardware
properties or completely arbitrary. If they are part of the hardware
design, it's probably a good idea to put them into some property
of the device tree, e.g. 'ti-c6x,dscr-id', and change the driver
interface to pass the 'struct device' directly, with the core code
looking at the contents of the property.
You could either have a table in the dscr node pointing to the
phandles of all devices controlled like this with the number used
as an index, or have one number in a property per device.
> +static void __init __setup_dscr(void)
> +{
> + struct device_node *node;
> +
> + node = of_find_compatible_node(NULL, NULL, "ti,tms320c6455-dscr");
> + if (!node)
> + return;
> +
> + dscr_base = of_iomap(node, 0);
> + of_node_put(node);
> + if (!dscr_base)
> + return;
> +
> + node = of_find_node_by_type(NULL, "soc");
> + if (node) {
> + chip_base = of_iomap(node, 0);
> + of_node_put(node);
> +
> + pr_info("DEVSTAT=%08x PERCFG0=%08x PERCFG1=%08x\n",
> + chip_read(CHIP_DEVSTAT), dscr_read(DSCR_PERCFG0),
> + dscr_read(DSCR_PERCFG1));
> + }
> +
> + SOC_DEVCONFIG_SUPPORT(TCP, DSCR_TCP);
> + SOC_DEVCONFIG_SUPPORT(VCP, DSCR_VCP);
> + SOC_DEVCONFIG_SUPPORT(EMAC, DSCR_EMAC);
> + SOC_DEVCONFIG_SUPPORT(TIMER, DSCR_TIMER0);
> + SOC_DEVCONFIG_SUPPORT(GPIO, DSCR_GPIO);
> + SOC_DEVCONFIG_SUPPORT(I2C, DSCR_I2C);
> + SOC_DEVCONFIG_SUPPORT(MCBSP, DSCR_BSP0);
> + SOC_DEVCONFIG_SUPPORT(HPI, DSCR_HPI);
> + SOC_DEVCONFIG_SUPPORT(PCI, DSCR_PCI);
> + SOC_DEVCONFIG_SUPPORT(UTOPIA, DSCR_UTOPIA);
> + SOC_DEVCONFIG_SUPPORT(SRIO, DSCR_SRIO);
> + SOC_DEVCONFIG_SUPPORT(EMIF, DSCR_EMIFA);
> + SOC_DEVCONFIG_SUPPORT(DDR2, DSCR_DDR2);
> +
> + c6455_dev_enable(SOC_DEV_TIMER, 0);
> + c6455_dev_enable(SOC_DEV_TIMER, 1);
> +
> +#ifdef CONFIG_I2C
> + c6455_dev_enable(SOC_DEV_I2C, 0);
> +#endif
> +#ifdef CONFIG_GENERIC_GPIO
> + c6455_dev_enable(SOC_DEV_GPIO, 0);
> +#endif
> +#ifdef CONFIG_TMS320C64X_GEMAC
> + c6455_dev_enable(SOC_DEV_EMAC, 0);
> +#endif
> +}
I believe you can even make this a generic dscr driver. For the most part,
the setup seems to be very similar across the four socs. The main difference
that I see is in the devices that you enable, and that can come from the
device tree, or be controlled by the device drivers calling a common function.
The #ifdef here seems completely misplaced however. Whether a device is
enabled or not should not depend on whether a driver is enabled or not.
There is also a small bug, since you do not check whether the drivers are
built as modules.
The 'node = of_find_node_by_type(NULL, "soc");' is bad style because you are
looking for a device_type, which you shouldn't do outside of the actual
Open Firmware client interface (that you don't have) and you match to a
very generic identifier ("soc"). It would be much better to match the
"compatible" value of the soc node, or perhaps to move the registers
into the dscr node and iomap both register sets from the same node
(slightly inaccurate though more readable).
> +static unsigned int c6455_silicon_rev(char **strp)
> +{
> + u32 jtagid = chip_read(CHIP_JTAGID);
> + u32 silicon_rev = (jtagid >> 28) & 0xf;
> +
> + if (strp) {
> + switch (silicon_rev) {
> + case 0:
> + *strp = "1.1";
> + break;
> + case 1:
> + *strp = "2.0";
> + break;
> + case 2:
> + *strp = "2.1";
> + break;
> + case 4:
> + *strp = "3.1";
> + break;
> + default:
> + *strp = "unknown";
> + break;
> + }
> + }
> + return silicon_rev;
> +}
Is this only informational? Is it actually worth having?
Maybe you can simply return the number instead of an ascii interpretation,
or you move this to the __setup_dscr function, which is an initcall, and
just remember the string.
> +static void __init c6455_setup_arch(void)
> +{
> + /* so we won't get called twice */
> + soc_ops.setup_arch = NULL;
> +
> + c6x_num_cores = 1;
> + __setup_dscr();
> + __setup_clocks();
> +}
> +
> +define_soc(tms320c6455) {
> + .compat = "ti,tms320c6455",
> + .name = "TMS320C6455",
The "name" field seems unnecessary here, when you can simply print
the actual "compatible" string of the present device.
> + .setup_arch = c6455_setup_arch,
> + .silicon_rev = c6455_silicon_rev,
> + .init_IRQ = megamod_pic_init,
> + .time_init = timer64_init,
The time_init and init_IRQ callbacks are the same for all socs,
so I suppose they could be hardcoded for now, instead of having
indirect calls.
Arnd
next prev parent reply other threads:[~2011-08-22 22:22 UTC|newest]
Thread overview: 54+ messages / expand[flat|nested] mbox.gz Atom feed top
2011-08-22 20:09 [PATCH v2 00/24] C6X: New architecture patch set Mark Salter
2011-08-22 20:09 ` [PATCH 01/24] fix default __strnlen_user macro Mark Salter
2011-08-22 20:09 ` [PATCH 02/24] fixed generic page.h for non-zero PAGE_OFFSET Mark Salter
2011-08-22 20:09 ` [PATCH 03/24] add ELF machine define for TI C6X DSPs Mark Salter
2011-08-22 20:09 ` [PATCH 04/24] C6X: build infrastructure Mark Salter
2011-08-22 20:55 ` Sam Ravnborg
2011-08-23 13:23 ` Mark Salter
2011-08-24 13:47 ` David Woodhouse
2011-08-24 14:10 ` Mark Salter
2011-08-22 20:09 ` [PATCH 05/24] C6X: early boot code Mark Salter
2011-08-22 20:09 ` [PATCH 06/24] C6X: devicetree Mark Salter
2011-08-22 20:09 ` [PATCH 07/24] C6X: memory management and DMA support Mark Salter
2011-08-22 20:09 ` [PATCH 08/24] C6X: process management Mark Salter
2011-08-22 20:55 ` Arnd Bergmann
2011-08-22 20:09 ` [PATCH 09/24] C6X: signal management Mark Salter
2011-08-22 20:09 ` [PATCH 10/24] C6X: time management Mark Salter
2011-08-22 20:09 ` [PATCH 11/24] C6X: interrupt handling Mark Salter
2011-08-22 20:58 ` Arnd Bergmann
2011-08-22 21:08 ` Mark Salter
2011-08-22 21:29 ` Benjamin Herrenschmidt
2011-08-22 20:09 ` [PATCH 12/24] C6X: syscalls Mark Salter
2011-08-22 21:00 ` Arnd Bergmann
2011-08-22 20:09 ` [PATCH 13/24] C6X: traps Mark Salter
2011-08-22 20:09 ` [PATCH 14/24] C6X: clocks Mark Salter
2011-08-22 20:09 ` [PATCH 15/24] C6X: cache control Mark Salter
2011-08-22 20:09 ` [PATCH 16/24] C6X: loadable module support Mark Salter
2011-08-22 21:04 ` Arnd Bergmann
2011-08-22 21:14 ` Mark Salter
2011-08-22 20:09 ` [PATCH 17/24] C6X: ptrace support Mark Salter
2011-08-22 21:07 ` Arnd Bergmann
2011-08-22 20:09 ` [PATCH 18/24] C6X: headers Mark Salter
2011-08-22 21:14 ` Arnd Bergmann
2011-08-23 13:43 ` Mark Salter
2011-08-24 4:53 ` Sam Ravnborg
2011-08-22 20:09 ` [PATCH 19/24] C6X: library code Mark Salter
2011-08-22 20:09 ` [PATCH 20/24] C6X: general SoC support Mark Salter
2011-08-22 20:09 ` [PATCH 21/24] C6X: specific " Mark Salter
2011-08-22 22:21 ` Arnd Bergmann [this message]
2011-08-22 20:09 ` [PATCH 22/24] C6X: EMIF - External Memory Interface Mark Salter
2011-08-22 21:17 ` Arnd Bergmann
2011-08-22 21:34 ` Mark Salter
2011-08-22 20:09 ` [PATCH 23/24] C6X: Power and Sleep Controller Mark Salter
2011-08-22 21:20 ` Arnd Bergmann
2011-08-22 21:32 ` Mark Salter
2011-08-22 20:09 ` [PATCH 24/24] C6X: MAINTAINERS Mark Salter
2011-08-22 22:25 ` [PATCH v2 00/24] C6X: New architecture patch set Arnd Bergmann
2011-09-26 14:31 ` Arnd Bergmann
2011-09-26 14:38 ` Mark Salter
2011-08-25 14:53 ` Peter Zijlstra
2011-08-25 16:00 ` Mark Salter
2011-08-25 17:27 ` Peter Zijlstra
2011-08-25 17:34 ` Mark Salter
2011-08-25 17:36 ` Peter Zijlstra
-- strict thread matches above, loose matches on Subject: below --
2011-08-08 21:44 [PATCH " Mark Salter
2011-08-08 21:44 ` [PATCH 21/24] C6X: specific SoC support Mark Salter
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=2642192.V7A2ih9bgf@wuerfel \
--to=arnd@arndb.de \
--cc=grant.likely@secretlab.ca \
--cc=linux-arch@vger.kernel.org \
--cc=msalter@redhat.com \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox