in intel-ixp4xx-eb.c [156:283]
static void ixp4xx_exp_setup_chipselect(struct ixp4xx_eb *eb,
struct device_node *np,
u32 cs_index,
u32 cs_size)
{
u32 cs_cfg;
u32 val;
u32 cur_cssize;
u32 cs_order;
int ret;
int i;
if (eb->is_42x && (cs_index > 7)) {
dev_err(eb->dev,
"invalid chipselect %u, we only support 0-7\n",
cs_index);
return;
}
if (eb->is_43x && (cs_index > 3)) {
dev_err(eb->dev,
"invalid chipselect %u, we only support 0-3\n",
cs_index);
return;
}
/* Several chip selects can be joined into one device */
if (cs_size > IXP4XX_EXP_STRIDE)
cur_cssize = IXP4XX_EXP_STRIDE;
else
cur_cssize = cs_size;
/*
* The following will read/modify/write the configuration for one
* chipselect, attempting to leave the boot defaults in place unless
* something is explicitly defined.
*/
regmap_read(eb->rmap, IXP4XX_EXP_TIMING_CS0 +
IXP4XX_EXP_TIMING_STRIDE * cs_index, &cs_cfg);
dev_info(eb->dev, "CS%d at %#08x, size %#08x, config before: %#08x\n",
cs_index, eb->bus_base + IXP4XX_EXP_STRIDE * cs_index,
cur_cssize, cs_cfg);
/* Size set-up first align to 2^9 .. 2^24 */
cur_cssize = roundup_pow_of_two(cur_cssize);
if (cur_cssize < 512)
cur_cssize = 512;
cs_order = ilog2(cur_cssize);
if (cs_order < 9 || cs_order > 24) {
dev_err(eb->dev, "illegal size order %d\n", cs_order);
return;
}
dev_dbg(eb->dev, "CS%d size order: %d\n", cs_index, cs_order);
cs_cfg &= ~(IXP4XX_EXP_SIZE_MASK);
cs_cfg |= ((cs_order - 9) << IXP4XX_EXP_SIZE_SHIFT);
for (i = 0; i < ARRAY_SIZE(ixp4xx_exp_tim_props); i++) {
const struct ixp4xx_exp_tim_prop *ip = &ixp4xx_exp_tim_props[i];
/* All are regular u32 values */
ret = of_property_read_u32(np, ip->prop, &val);
if (ret)
continue;
/* Handle bools (single bits) first */
if (ip->max == 1) {
if (val)
cs_cfg |= ip->mask;
else
cs_cfg &= ~ip->mask;
dev_info(eb->dev, "CS%d %s %s\n", cs_index,
val ? "enabled" : "disabled",
ip->prop);
continue;
}
if (val > ip->max) {
dev_err(eb->dev,
"CS%d too high value for %s: %u, capped at %u\n",
cs_index, ip->prop, val, ip->max);
val = ip->max;
}
/* This assumes max value fills all the assigned bits (and it does) */
cs_cfg &= ~ip->mask;
cs_cfg |= (val << ip->shift);
dev_info(eb->dev, "CS%d set %s to %u\n", cs_index, ip->prop, val);
}
ret = of_property_read_u32(np, "intel,ixp4xx-eb-cycle-type", &val);
if (!ret) {
if (val > 3) {
dev_err(eb->dev, "illegal cycle type %d\n", val);
return;
}
dev_info(eb->dev, "CS%d set cycle type %d\n", cs_index, val);
cs_cfg &= ~IXP4XX_EXP_CYC_TYPE_MASK;
cs_cfg |= val << IXP4XX_EXP_CYC_TYPE_SHIFT;
}
if (eb->is_42x)
cs_cfg &= ~IXP42X_RESERVED;
if (eb->is_43x) {
cs_cfg &= ~IXP43X_RESERVED;
/*
* This bit for Intel strata flash is currently unused, but let's
* report it if we find one.
*/
if (cs_cfg & IXP43X_EXP_SYNC_INTEL)
dev_info(eb->dev, "claims to be Intel strata flash\n");
}
cs_cfg |= IXP4XX_EXP_CS_EN;
regmap_write(eb->rmap,
IXP4XX_EXP_TIMING_CS0 + IXP4XX_EXP_TIMING_STRIDE * cs_index,
cs_cfg);
dev_info(eb->dev, "CS%d wrote %#08x into CS config\n", cs_index, cs_cfg);
/*
* If several chip selects are joined together into one big
* device area, we call ourselves recursively for each successive
* chip select. For a 32MB flash chip this results in two calls
* for example.
*/
if (cs_size > IXP4XX_EXP_STRIDE)
ixp4xx_exp_setup_chipselect(eb, np,
cs_index + 1,
cs_size - IXP4XX_EXP_STRIDE);
}