Re: Tegra30 work around broken firmware.

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



On 03.03.2018 02:32, Peter Geis wrote:
> Good Evening,
> 
> 
> Thank you very much, I can confirm this patch solved the L2 cache issue.
> 
> Still working through the hard lock, currently occurring when the regulators
> enable.

I haven't got my hands on porting regulator driver of my T30 to the current
upstream. In my experience proprietary bootloader enables and ramps everything
to max before jumping to kernel. So you may try just to omit regulators for the
starter, like I do.

> Clock patch didn't change the hard lock point, but I'm likely locking before it
> would have mattered.
> 
> Now back to working out the issues with my device tree, I'll let you know if I
> run into any new roadblocks.

I may suggest to strip DT to bare minimum, so that display lights up and your
favorite Linux distro boots up, only after that enable the rest of HW step by step.

> If you have any further insights or have patches to test, please do not hesitate
> to contact me.

For now I don't have any more patches to suggest, everything should work if your
DT is correct.

> On 03/02/2018 12:05 PM, Dmitry Osipenko wrote:
>> On 02.03.2018 16:27, Peter Geis wrote:
>>> Good Morning,
>>>
>>>
>>> I have an OUYA console that I am attempting to get the 4.14 kernel booted on.
>>>
>>> It is a Tegra30-Cardhu based system, which from what I can tell had as many
>>> corners cut during development as possible.
>>>
>>> I do not have access to the firmware itself, and the firmware does not support
>>> anything beyond 3.1.10, so I am using a kernel appended DTB.
>>>
>>> The issue I'm running into right now is I cannot get the layer 2 cache
>>> controller, a PL310, to init correctly.
>>>
>>> I can disable the function, and I boot till DMA starts accessing hardware and go
>>> into a hard lock.
>>>
>>> If I have the L2C enabled, it kernel panics during L2c310_configure, while
>>> trying to write the secure registers.
>>>
>>> I am pretty sure the firmware is not using secure mode at all, and in the
>>> cache-l2x0.c source the function states "By default, we write directly to secure
>>> registers.  Platforms must override this if they are running non-secure."
>>>
>>> I unfortunately cannot figure out how to override this function.
>>>
>>> I would like to keep all or as much as possible any code modification to the
>>> device tree and kernel configuration only.
>>>
>>>
>>> Is there a way via the device tree to override secure mode?
>>>
>>> I have included a full boot log up until the panic.
>> Hello Peter,
>>
>> Your device uses fastboot, so it's likely to be proprietary bootloader that
>> boots kernel under secure monitor. Upstream kernel doesn't support the secured
>> L2. Michał implemented the support about a half year ago, but the patches
>> required some rework to get into upstream. Unfortunately seems Michał haven't
>> had time to address the review comments and send a new version of the patches,
>> so they are stuck since then.
>>
>> Michał, are you planning to continue working on the patches? If not, I may try
>> to refresh them and re-send. (CC'ed Michał)
>>
>> Below is the summarized diff against linux-next (you may need to do some
>> backporting to 4.14) that you need to apply to get things working. Also don't
>> forget to add TF node to your DT:
>>
>> firmware {
>>     trusted-foundations {
>>         compatible = "tlm,trusted-foundations";
>>         tlm,version-major = <0x2>;
>>         tlm,version-minor = <0x8>;
>>     };
>> };
>>
>> If you are going to try a newer kernel, note that it may not work with the
>> proprietary bootloader without this patch [0].
>>
>> [0] https://patchwork.ozlabs.org/patch/858304/
>>
>> Also, if you'll experience some odd memory-controller errors, try to disable
>> CONFIG_TEGRA_IOMMU_SMMU in the kernel config.
>>
>> diff --git a/arch/arm/firmware/trusted_foundations.c
>> b/arch/arm/firmware/trusted_foundations.c
>> index 3fb1b5a1dce9..44e9cac57e78 100644
>> --- a/arch/arm/firmware/trusted_foundations.c
>> +++ b/arch/arm/firmware/trusted_foundations.c
>> @@ -17,11 +17,19 @@
>>   #include <linux/kernel.h>
>>   #include <linux/init.h>
>>   #include <linux/of.h>
>> +#include <asm/io.h>
>>   #include <asm/firmware.h>
>> +#include <asm/outercache.h>
>> +#include <asm/hardware/cache-l2x0.h>
>>   #include <asm/trusted_foundations.h>
>>
>> +#define TF_CACHE_MAINT           0xfffff100
>>   #define TF_SET_CPU_BOOT_ADDR_SMC 0xfffff200
>>
>> +#define TF_CACHE_INIT        1
>> +#define TF_CACHE_FLUSH        2
>> +#define TF_CACHE_REENABLE    4
>> +
>>   #define TF_CPU_PM        0xfffffffc
>>   #define TF_CPU_PM_S3        0xffffffe3
>>   #define TF_CPU_PM_S2        0xffffffe6
>> @@ -63,9 +71,48 @@ static int tf_prepare_idle(void)
>>       return 0;
>>   }
>>
>> +#ifdef CONFIG_CACHE_L2X0
>> +static void tf_write_sec(unsigned long val, unsigned reg)
>> +{
>> +    unsigned long cur = readl_relaxed(l2x0_base + reg);
>> +
>> +    pr_warn("TF: ignoring write_sec[0x%x]: 0x%08lx -> 0x%08lx\n",
>> +        reg, cur, val);
>> +}
>> +
>> +static void tf_disable_cache(void)
>> +{
>> +    tf_generic_smc(TF_CACHE_MAINT, TF_CACHE_FLUSH, l2x0_way_mask);
>> +}
>> +
>> +static void tf_resume_cache(void)
>> +{
>> +    unsigned long aux_val = readl_relaxed(l2x0_base + L2X0_AUX_CTRL);
>> +    tf_generic_smc(TF_CACHE_MAINT, TF_CACHE_REENABLE, aux_val);
>> +}
>> +
>> +static void tf_configure_cache(const struct l2x0_regs *regs)
>> +{
>> +    outer_cache.disable = tf_disable_cache;
>> +    outer_cache.resume = tf_resume_cache;
>> +}
>> +
>> +static int tf_init_cache(void)
>> +{
>> +    tf_generic_smc(TF_CACHE_MAINT, TF_CACHE_INIT, 0);
>> +
>> +    outer_cache.write_sec = tf_write_sec;
>> +    outer_cache.configure = tf_configure_cache;
>> +    return 0;
>> +}
>> +#endif /* CONFIG_CACHE_L2X0 */
>> +
>>   static const struct firmware_ops trusted_foundations_ops = {
>>       .set_cpu_boot_addr = tf_set_cpu_boot_addr,
>>       .prepare_idle = tf_prepare_idle,
>> +#ifdef CONFIG_CACHE_L2X0
>> +    .l2x0_init = tf_init_cache,
>> +#endif
>>   };
>>
>>   void register_trusted_foundations(struct trusted_foundations_platform_data *pd)
>> @@ -96,4 +143,6 @@ void of_register_trusted_foundations(void)
>>       if (err != 0)
>>           panic("Trusted Foundation: missing version-minor property\n");
>>       register_trusted_foundations(&pdata);
>> +
>> +    of_node_put(node);
>>   }
>> diff --git a/arch/arm/include/asm/hardware/cache-l2x0.h
>> b/arch/arm/include/asm/hardware/cache-l2x0.h
>> index 736292b42fca..603cc55edbd0 100644
>> --- a/arch/arm/include/asm/hardware/cache-l2x0.h
>> +++ b/arch/arm/include/asm/hardware/cache-l2x0.h
>> @@ -193,6 +193,8 @@ struct l2x0_regs {
>>       unsigned long aux2_ctrl;
>>   };
>>
>> +extern void __iomem *l2x0_base;
>> +extern u32 l2x0_way_mask;
>>   extern struct l2x0_regs l2x0_saved_regs;
>>
>>   #endif /* __ASSEMBLY__ */
>> diff --git a/arch/arm/mm/cache-l2x0.c b/arch/arm/mm/cache-l2x0.c
>> index 808efbb89b88..1b29b769b6a9 100644
>> --- a/arch/arm/mm/cache-l2x0.c
>> +++ b/arch/arm/mm/cache-l2x0.c
>> @@ -30,6 +30,7 @@
>>   #include <asm/cp15.h>
>>   #include <asm/cputype.h>
>>   #include <asm/hardware/cache-l2x0.h>
>> +#include <asm/firmware.h>
>>   #include "cache-tauros3.h"
>>   #include "cache-aurora-l2.h"
>>
>> @@ -37,6 +38,7 @@ struct l2c_init_data {
>>       const char *type;
>>       unsigned way_size_0;
>>       unsigned num_lock;
>> +    void (*init)(void __iomem *, u32 *, u32 *);
>>       void (*of_parse)(const struct device_node *, u32 *, u32 *);
>>       void (*enable)(void __iomem *, unsigned);
>>       void (*fixup)(void __iomem *, u32, struct outer_cache_fns *);
>> @@ -48,13 +50,13 @@ struct l2c_init_data {
>>
>>   #define CACHE_LINE_SIZE        32
>>
>> -static void __iomem *l2x0_base;
>>   static const struct l2c_init_data *l2x0_data;
>>   static DEFINE_RAW_SPINLOCK(l2x0_lock);
>> -static u32 l2x0_way_mask;    /* Bitmask of active ways */
>>   static u32 l2x0_size;
>>   static unsigned long sync_reg_offset = L2X0_CACHE_SYNC;
>>
>> +void __iomem *l2x0_base;
>> +u32 l2x0_way_mask;    /* Bitmask of active ways */
>>   struct l2x0_regs l2x0_saved_regs;
>>
>>   static bool l2x0_bresp_disable;
>> @@ -1758,6 +1760,7 @@ int __init l2x0_of_init(u32 aux_val, u32 aux_mask)
>>       u32 cache_id, old_aux;
>>       u32 cache_level = 2;
>>       bool nosync = false;
>> +    int err;
>>
>>       np = of_find_matching_node(NULL, l2x0_ids);
>>       if (!np)
>> @@ -1798,6 +1801,11 @@ int __init l2x0_of_init(u32 aux_val, u32 aux_mask)
>>
>>       nosync = of_property_read_bool(np, "arm,outer-sync-disable");
>>
>> +    /* Call firmware init */
>> +    err = call_firmware_op(l2x0_init);
>> +    if (err && err != -ENOSYS)
>> +        return err;
>> +
>>       /* Read back current (default) hardware configuration */
>>       if (data->save)
>>           data->save(l2x0_base);
>> diff --git a/arch/arm/mach-tegra/reset-handler.S
>> b/arch/arm/mach-tegra/reset-handler.S
>> index 805f306fa6f7..9a92bbf8b5b0 100644
>> --- a/arch/arm/mach-tegra/reset-handler.S
>> +++ b/arch/arm/mach-tegra/reset-handler.S
>> @@ -80,6 +80,28 @@ ENTRY(tegra_resume)
>>   #endif
>>
>>   #ifdef CONFIG_CACHE_L2X0
>> +#ifdef CONFIG_TRUSTED_FOUNDATIONS
>> +    adr    r3, __tegra_cpu_reset_handler_data
>> +    ldr    r0, [r3, #RESET_DATA(TF_PRESENT)]
>> +    cmp    r0, #0
>> +    beq    ca9_scu_l2_resume
>> +
>> +    adr    r3, __tegra_smc_stack
>> +    stmia    r3, {r4-r12, sp, lr}
>> +
>> +    mov    r0, #3    // local wake
>> +    mov    r3, #0
>> +    mov    r4, #0
>> +    dsb
>> +    .arch_extension    sec
>> +    smc    #0
>> +
>> +    adr    r3, __tegra_smc_stack
>> +    ldmia    r3, {r4-r12, sp, pc}
>> +
>> +    b    end_ca9_scu_l2_resume
>> +ca9_scu_l2_resume:
>> +#endif
>>       /* L2 cache resume & re-enable */
>>       bl    l2c310_early_resume
>>   #endif
>> @@ -92,6 +114,16 @@ end_ca9_scu_l2_resume:
>>   ENDPROC(tegra_resume)
>>   #endif
>>
>> +#ifdef CONFIG_TRUSTED_FOUNDATIONS
>> +    .align L1_CACHE_SHIFT
>> +    .type __tegra_smc_stack, %object
>> +__tegra_smc_stack:
>> +    .rept 11
>> +    .long 0
>> +    .endr
>> +    .size __tegra_smc_stack, . - __tegra_smc_stack
>> +#endif /* CONFIG_TRUSTED_FOUNDATIONS */
>> +
>>       .align L1_CACHE_SHIFT
>>   ENTRY(__tegra_cpu_reset_handler_start)
>>
>> @@ -121,6 +153,12 @@ ENTRY(__tegra_cpu_reset_handler)
>>       cpsid    aif, 0x13            @ SVC mode, interrupts disabled
>>
>>       tegra_get_soc_id TEGRA_APB_MISC_BASE, r6
>> +
>> +    adr    r5, __tegra_cpu_reset_handler_data
>> +    ldr    r0, [r5, #RESET_DATA(TF_PRESENT)]
>> +    cmp    r0, #0
>> +    bne    after_errata
>> +
>>   #ifdef CONFIG_ARCH_TEGRA_2x_SOC
>>   t20_check:
>>       cmp    r6, #TEGRA20
>> @@ -285,6 +323,10 @@ __tegra_cpu_reset_handler_data:
>>       .equ    __tegra20_cpu1_resettable_status_offset, \
>>                       . - __tegra_cpu_reset_handler_start
>>       .byte    0
>> +    .align    4
>> +    .globl    __tegra_tf_present
>> +    .equ    __tegra_tf_present, . - __tegra_cpu_reset_handler_start
>> +    .long    0
>>       .align L1_CACHE_SHIFT
>>
>>   ENTRY(__tegra_cpu_reset_handler_end)
>> diff --git a/arch/arm/mach-tegra/reset.c b/arch/arm/mach-tegra/reset.c
>> index dc558892753c..9b6558a69308 100644
>> --- a/arch/arm/mach-tegra/reset.c
>> +++ b/arch/arm/mach-tegra/reset.c
>> @@ -18,6 +18,7 @@
>>   #include <linux/cpumask.h>
>>   #include <linux/init.h>
>>   #include <linux/io.h>
>> +#include <linux/of.h>
>>
>>   #include <soc/tegra/fuse.h>
>>
>> @@ -89,6 +90,15 @@ static void __init tegra_cpu_reset_handler_enable(void)
>>
>>   void __init tegra_cpu_reset_handler_init(void)
>>   {
>> +#ifdef CONFIG_TRUSTED_FOUNDATIONS
>> +    struct device_node *np;
>> +
>> +    np = of_find_compatible_node(NULL, NULL, "tlm,trusted-foundations");
>> +    if (np) {
>> +        __tegra_cpu_reset_handler_data[TEGRA_RESET_TF_PRESENT] = true;
>> +        of_node_put(np);
>> +    }
>> +#endif
>>
>>   #ifdef CONFIG_SMP
>>       __tegra_cpu_reset_handler_data[TEGRA_RESET_MASK_PRESENT] =
>> diff --git a/arch/arm/mach-tegra/reset.h b/arch/arm/mach-tegra/reset.h
>> index 9c479c7925b8..0d9ddc022ece 100644
>> --- a/arch/arm/mach-tegra/reset.h
>> +++ b/arch/arm/mach-tegra/reset.h
>> @@ -25,7 +25,9 @@
>>   #define TEGRA_RESET_STARTUP_SECONDARY    3
>>   #define TEGRA_RESET_STARTUP_LP2        4
>>   #define TEGRA_RESET_STARTUP_LP1        5
>> -#define TEGRA_RESET_DATA_SIZE        6
>> +#define TEGRA_RESET_RESETTABLE_STATUS    6
>> +#define TEGRA_RESET_TF_PRESENT        7
>> +#define TEGRA_RESET_DATA_SIZE        8
>>
>>   #ifndef __ASSEMBLY__
>>
>>
> 

--
To unsubscribe from this list: send the line "unsubscribe linux-tegra" in
the body of a message to majordomo@xxxxxxxxxxxxxxx
More majordomo info at  http://vger.kernel.org/majordomo-info.html



[Index of Archives]     [ARM Kernel]     [Linux ARM]     [Linux ARM MSM]     [Linux USB Devel]     [Video for Linux]     [Linux Audio Users]     [Yosemite News]     [Linux Kernel]     [Linux SCSI]

  Powered by Linux